#pragma once

#include "client/ui/ui_event.h"
#include "spdlog/spdlog.h"
#include <RmlUi/Core.h>
#include <RmlUi/Debugger.h>
#include <RmlUi_Backend.h>
#include <utility>
#include <vector>

using Rml::DataModelHandle;
using Rml::Event;
using Rml::VariantList;
using std::vector;

namespace UI::AdminMenu {

class Page {
  public:
    Rml::ElementDocument *document = nullptr;

    void initialize(Rml::Context *context) {
        if (Rml::DataModelConstructor constructor = context->CreateDataModel("admin_menu")) {
            constructor.BindEventCallback(
                "on_close",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_close");
                    ui_events.push_back(UiEvent::Close);
                });

            constructor.BindEventCallback(
                "on_open_login",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_login");
                    ui_events.push_back(UiEvent::OpenLogin);
                });

            constructor.BindEventCallback(
                "on_open_match_finder",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_match_finder");
                    ui_events.push_back(UiEvent::OpenMatchFinder);
                });

            constructor.BindEventCallback(
                "on_open_loading_match",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_loading_match");
                    ui_events.push_back(UiEvent::OpenLoadingMatch);
                });

            constructor.BindEventCallback(
                "on_open_buy_loadout",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_buy_loadout");
                    ui_events.push_back(UiEvent::OpenBuyLoadout);
                });

            constructor.BindEventCallback(
                "on_open_view_loadouts",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_view_loadouts");
                    ui_events.push_back(UiEvent::OpenViewLoadouts);
                });

            constructor.BindEventCallback(
                "on_open_edit_loadout",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_edit_loadout");
                    ui_events.push_back(UiEvent::OpenEditLoadout);
                });

            constructor.BindEventCallback(
                "on_open_ship_editor",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_ship_editor");
                    ui_events.push_back(UiEvent::OpenShipEditor);
                });

            constructor.BindEventCallback(
                "on_open_mount_editor",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_mount_editor");
                    ui_events.push_back(UiEvent::OpenMountEditor);
                });

            constructor.BindEventCallback(
                "on_open_projectile_editor",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_projectile_editor");
                    ui_events.push_back(UiEvent::OpenProjectileEditor);
                });

            constructor.BindEventCallback(
                "on_open_server_browser",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_server_browser");
                    ui_events.push_back(UiEvent::OpenServerBrowser);
                });

            constructor.BindEventCallback(
                "on_open_server_lobby",
                [this](DataModelHandle, Event &, const VariantList &) {
                    SPDLOG_INFO("admin_menu: on_open_server_lobby");
                    ui_events.push_back(UiEvent::OpenServerLobby);
                });

            document = context->LoadDocument("build/assets/ui/pages/admin_menu/admin_menu.rml");
        }
    }

    void show() {
        document->Show();
    }

    void hide() {
        document->Hide();
    }

    vector<UiEvent> drain_ui_events() {
        return std::exchange(ui_events, {});
    }

  private:
    vector<UiEvent> ui_events;
};

} // namespace UI::AdminMenu
