#include <wx/wx.h>
#include <wx/file.h>
#include <wx/filename.h>
#include <wx/stdpaths.h>
#include <wx/datetime.h>
#include "MainFrame.h"
#include "SplashDialog.h"
#include "Prefs.h"
#include "panels/PropertiesPanel.h"
#include "io/CatalogLoader.h"

static wxFile* g_log = nullptr;

void TDLog(const wxString& msg) {
    if (g_log && g_log->IsOpened()) {
        wxString line = wxDateTime::Now().Format("%H:%M:%S.%l ") + msg + "\n";
        g_log->Write(line.c_str(), line.length());
        g_log->Flush();
    }
}

// Returns %LOCALAPPDATA%\TrackDesigner, creating it if needed.
// Falls back to the temp dir if appdata isn't accessible.
static wxString GetUserDataDir() {
    wxString dir = wxStandardPaths::Get().GetUserLocalDataDir();
    if (!wxFileName::DirExists(dir)) {
        wxFileName::Mkdir(dir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    }
    if (!wxFileName::DirExists(dir)) {
        dir = wxStandardPaths::Get().GetTempDir();
    }
    return dir;
}

class TrackDesignerApp : public wxApp {
public:
    bool OnInit() override {
        g_log = new wxFile();
        wxString logPath = GetUserDataDir() + wxFileName::GetPathSeparator() + "trackdesigner.log";
        g_log->Open(logPath, wxFile::write);
        TDLog("=== TrackDesigner starting ===");

        // Catalog is built-in — no file needed
        auto& catalog = MC::GetCatalog();
        wxString countStr;
        countStr << catalog.Count();
        TDLog("Built-in catalog loaded - " + countStr + " pieces");

        TDLog("Creating MainFrame...");
        MainFrame* frame = nullptr;
        try {
            frame = new MainFrame();
            TDLog("MainFrame created OK");
        } catch (const std::exception& e) {
            TDLog(wxString("EXCEPTION: ") + e.what());
            return false;
        } catch (...) {
            TDLog("UNKNOWN EXCEPTION in MainFrame");
            return false;
        }

        frame->Show(true);
        TDLog("Show OK");
        // Ensure default level exists
        frame->State().EnsureDefaultLevel();

        // Load preferences before deciding whether to show the splash.
        // Prefs are also loaded in MainFrame ctor but that's fine — the
        // Load() is idempotent and the file is tiny.
        Prefs::Get().Load();

        // Show splash welcome dialog only in playful mode.
        if (Prefs::Get().IsPlayful()) {
            SplashDialog splash(frame);
            splash.ShowModal();
        }
        frame->Properties()->RefreshTally();

        return true;
    }

    int OnExit() override {
        TDLog("OnExit");
        if (g_log) { g_log->Close(); delete g_log; g_log = nullptr; }
        return 0;
    }
};

wxIMPLEMENT_APP(TrackDesignerApp);
