#include "OnLineControl.h"
#include "HeaderControl.h"
#include "LogControl.h"
#include "RemoteControl.h"
#include <ClientCore.h>

OnlineControl::OnlineControl(wxWindow* parent, std::shared_ptr<ClientCore>& clientCore) : wxPanel(parent), clientCore_(clientCore)
{
    Init();
    InitCall();
    BindEvent();
}

OnlineControl::~OnlineControl()
{
}

void OnlineControl::SetHeaderControl(HeaderControl* headerControl)
{
    headerControl_ = headerControl;
}

void OnlineControl::SetLogControl(LogControl* logControl)
{
    logControl_ = logControl;
}

void OnlineControl::SetRemoteControl(RemoteControl* remoteControl)
{
    remoteControl_ = remoteControl;
}

void OnlineControl::Init()
{
    btnFresh_ = new wxButton(this, wxID_ANY, _("Refresh"));
    lbCurState_ = new wxStaticText(this, wxID_ANY, _("Current State => "));
    elbCurState_ = new wxStaticText(this, wxID_ANY, _("Disconnected"));
    elbCurState_->SetForegroundColour(*wxBLUE);
    onLineList_ = new wxListBox(this, wxID_ANY);
    // 设置 onLineList_ 只能单选
    onLineList_->SetWindowStyle(wxLB_SINGLE);

    lbCurPoint_ = new wxStaticText(this, wxID_ANY, _("Commnunicate Point => "));
    elbCurPoint_ = new wxStaticText(this, wxID_ANY, _("None"));
    elbCurPoint_->SetForegroundColour(*wxBLUE);

    auto* leveSizerA = new wxBoxSizer(wxHORIZONTAL);
    leveSizerA->Add(lbCurState_, 0, wxEXPAND | wxALL, gBorder + 1);
    leveSizerA->Add(elbCurState_, 0, wxEXPAND | wxALL, gBorder + 1);

    auto* leveSizerB = new wxBoxSizer(wxHORIZONTAL);
    leveSizerB->Add(lbCurPoint_, 1, wxALL | wxCENTER, gBorder + 1);
    leveSizerB->Add(btnFresh_, 0, wxALL | wxCENTER, gBorder + 1);

    auto* topSizer = new wxBoxSizer(wxVERTICAL);
    topSizer->Add(leveSizerA, 0, wxEXPAND | wxALL, gBorder + 1);
    topSizer->Add(leveSizerB, 0, wxALL, gBorder + 1);
    topSizer->Add(elbCurPoint_, 0, wxEXPAND | wxALL, gBorder + 1);
    topSizer->Add(onLineList_, 1, wxEXPAND | wxALL, gBorder + 1);
    SetSizer(topSizer);
    Layout();

    menu_ = new wxMenu;
    useId_ = wxNewId();
    menu_->Append(useId_, _("Use this client"));
}

void OnlineControl::BindEvent()
{
    Bind(wxEVT_BUTTON, &OnlineControl::OnFreshClients, this, btnFresh_->GetId());
    onLineList_->Bind(wxEVT_CONTEXT_MENU, [&](wxContextMenuEvent& event) {
        auto p = event.GetPosition();
        p = onLineList_->ScreenToClient(p);
        onLineList_->PopupMenu(menu_, p);
    });
    Bind(wxEVT_MENU, &OnlineControl::UseThisClient, this, useId_);
}

void OnlineControl::SetConnectState(const wxString& state)
{
    elbCurState_->SetLabel(state);
}

void OnlineControl::SetConnectServer(const wxString& server)
{
    elbCurPoint_->SetLabel(server);
}

void OnlineControl::ClearClientsShow()
{
    std::unique_lock<std::mutex> lock(mutex_);
    onLineList_->Clear();
}

void OnlineControl::InitCall()
{
    clientCore_->ReqOnlineCallback([this](const InfoClientVec& infoClientVec) { OnFreshClientsCall(infoClientVec); });
}

void OnlineControl::OnFreshClients(wxCommandEvent& event)
{
    if (!clientCore_->IsOk()) {
        logControl_->AddLog(_("You have not established a connection with the server."));
        return;
    }
    InfoClientVec vec;
    if (!clientCore_->ReqOnline()) {
        logControl_->AddLog(_("The request to obtain the client list was failed."));
        return;
    }
    logControl_->AddLog(_("The request to obtain the client list was successful."));
}

void OnlineControl::OnFreshClientsCall(const InfoClientVec& infoClientVec)
{
    std::unique_lock<std::mutex> lock(mutex_);
    onLineList_->Clear();
    for (auto& info : infoClientVec.vec) {
        onLineList_->Append(info.id);
    }
    logControl_->AddLog(_("Get online list success."));
}

void OnlineControl::UseThisClient(wxCommandEvent& event)
{
    int selection = onLineList_->GetSelection();
    if (selection != wxNOT_FOUND) {
        wxString selectedText = onLineList_->GetString(selection);
        if (clientCore_->GetOwnId() == selectedText) {
            wxMessageDialog dialog(this, _("You selected yourself, do you want to use yourself?"), _("Confirm"),
                                   wxYES_NO | wxICON_QUESTION);
            if (dialog.ShowModal() == wxID_YES) {
                remoteControl_->setRemoteID(selectedText);
            }
            return;
        }
        remoteControl_->setRemoteID(selectedText);
    }
}