#pragma once

#include <memory>
#include <string>

#include "presentation/overlays/esp/EspOverlayRenderer.h"
#include "presentation/overlays/watermark/WatermarkOverlayRenderer.h"
#include "presentation/pages/PageId.h"
#include "presentation/MenuPorts.h"
#include "features/quests/contracts/IQuestCommands.h"
#include "features/quests/contracts/IQuestQueries.h"
#include "features/watermark/IWatermarkQueries.h"
#include "features/items/contracts/IItemCommands.h"
#include "features/items/contracts/IItemQueries.h"
#include "features/esp/contracts/IEspQueries.h"
#include "application/contracts/IKeyInput.h"
#include "application/contracts/UiCommands.h"
#include "application/contracts/UiReadModel.h"

namespace ta::presentation
{
    using ta::ui::ConfigCommand;
    using ta::ui::ConfigCommandType;
    using ta::ui::ConfigControlKind;
    using ta::ui::ConfigPanelSnapshot;
    using ta::ui::ConfigUiSnapshot;
    using ta::ui::ConfigValueSnapshot;
    using ta::ui::DiagnosticsSnapshot;
    using ta::ui::UiCommands;
    using ta::ui::UiShellSnapshot;
    struct UiState;

    class ConfigCommandSubmitter final
    {
    public:
        ConfigCommandSubmitter() = default;
        ConfigCommandSubmitter(UiCommands* commands, ta::application::IKeyInput* key_input) noexcept
            : commands_(commands), key_input_(key_input) {}

        [[nodiscard]] explicit operator bool() const noexcept { return commands_ != nullptr; }
        void operator()(ConfigCommand command) const;
        [[nodiscard]] ta::application::IKeyInput* key_input() const noexcept { return key_input_; }

    private:
        UiCommands* commands_ = nullptr;
        ta::application::IKeyInput* key_input_ = nullptr;
    };

    struct ItemsPageContext
    {
        std::shared_ptr<const ta::features::items::contracts::ItemCatalogSnapshot> catalog;
        bool in_raid = false;
        ConfigCommandSubmitter submit_config;
        ta::features::items::contracts::IItemCommands* commands = nullptr;
    };

    struct QuestsPageContext
    {
        bool in_raid = false;
        ta::features::quests::contracts::IQuestQueries* queries = nullptr;
        ta::features::quests::contracts::IQuestCommands* commands = nullptr;
    };

    struct MenuContext
    {
        bool valid = false;
        bool in_raid = false;
        bool has_aimbot = false;
        int menu_key = 0x2D;
        ta::application::IKeyInput* key_input = nullptr;

        std::shared_ptr<const ConfigUiSnapshot> config;
        DiagnosticsSnapshot diagnostics;
        ConfigCommandSubmitter submit_config;
        ItemsPageContext items;
        QuestsPageContext quests;

        ta::presentation::overlays::watermark::WatermarkOverlayData watermark;
        ta::presentation::overlays::esp::EspOverlayDrawData esp;
    };

    [[nodiscard]] MenuContext build_menu_context(
        const UiShellSnapshot& model,
        MenuPorts& ports,
        UiState& state);
}
