#include "UserInterface.h"
#include <Util.h>
#include <filesystem>
#include <wx/fileconf.h>

namespace fs = std::filesystem;

UserInterface::UserInterface(const wxString& title) : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxSize(800, 600))
{
    mgr_.SetManagedWindow(this);

    clientCore_ =  std::make_shared<ClientCore>();

    InitMenu();
    InitUI();
    InitData();
    TryRestoreLayout();

    Bind(wxEVT_CLOSE_WINDOW, &UserInterface::OnClose, this);
    controlMgr_->log_->AddLog(wxT("Welcome to RelayFile."));
}

UserInterface::~UserInterface()
{
    mgr_.UnInit();
}

void UserInterface::OnClose(wxCloseEvent& event)
{
    auto* config = new wxFileConfig(wxEmptyString, wxEmptyString, configPath_);
    config->Write("StartWidth", GetSize().GetWidth());
    config->Write("StartHeigh", GetSize().GetHeight());
    delete config;
    event.Skip();
}

void UserInterface::InitUI()
{
    // Add Panel
    controlMgr_ = std::make_shared<ControlManager>(this);
    controlMgr_->Init(clientCore_);
    mgr_.AddPane(controlMgr_->header_,
                 wxAuiPaneInfo().Name("header").Caption(_("header")).CloseButton(false).Floatable(false).MinSize(-1, 40));
    mgr_.AddPane(controlMgr_->log_, wxAuiPaneInfo().Name("log").Caption(_("log")).CloseButton(false).BestSize(300, 400));
    mgr_.AddPane(controlMgr_->local_,
                 wxAuiPaneInfo().Name("local").Caption(_("local")).CloseButton(false).BestSize(300, 400).Bottom());
    mgr_.AddPane(controlMgr_->remote_,
                 wxAuiPaneInfo().Name("remote").Caption(_("remote")).CloseButton(false).BestSize(300, 400).Bottom());
    mgr_.AddPane(controlMgr_->task_,
                 wxAuiPaneInfo().Name("task").Caption(_("task")).CloseButton(false).BestSize(300, 400).CenterPane());
    mgr_.AddPane(controlMgr_->online_,
                 wxAuiPaneInfo().Name("online").Caption(_("online")).CloseButton(false).BestSize(300, 400).Right());
    // update
    mgr_.Update();
}

void UserInterface::InitMenu()
{
    menuBar_ = new wxMenuBar();
    wxMenu* auimenu = new wxMenu();
    auimenu->Append(ID_SaveLayout, "&SaveLayout\tCtrl-S", _("Save Layout"));
    menuBar_->Append(auimenu, "&Aui");
    SetMenuBar(menuBar_);

    Bind(wxEVT_MENU, &UserInterface::OnSaveLayout, this, ID_SaveLayout);
}

void UserInterface::InitData()
{
    auto configDir = wxUtil::GetConfigDir();
    wxUtil::CreateConfigDir(configDir, wxT("RelayFile"), configDir_);
    configPath_ = configDir_ + wxT("/RelayFile.ini");
}

void UserInterface::TryRestoreLayout()
{
    fs::path path(configPath_.ToStdString());
    if (!fs::exists(path)) {
        return;
    }
    auto* config = new wxFileConfig(wxEmptyString, wxEmptyString, configPath_);
    wxString perspective = config->Read("perspective");
    if (!perspective.IsEmpty()) {
        mgr_.LoadPerspective(perspective);
    }
    auto startWidth = config->Read("StartWidth", 800);
    auto startHeigh = config->Read("StartHeigh", 600);
    SetSize(startWidth, startHeigh);
    delete config;
}

void UserInterface::OnSaveLayout(wxCommandEvent& event)
{
    auto perspective = mgr_.SavePerspective();
    auto* config = new wxFileConfig(wxEmptyString, wxEmptyString, configPath_);
    if (config->Write("perspective", perspective)) {
        config->Flush();
        wxMessageBox(_("Save Layout Success"), _("Save Layout"), wxOK | wxICON_INFORMATION);
    } else {
        wxMessageBox(_("Save Layout Failed"), _("Save Layout"), wxOK | wxICON_ERROR);
    }
    delete config;
}