#include "presentation/MenuContext.h"

#include <algorithm>
#include <utility>

#include "presentation/overlays/esp/EspOverlayBuilder.h"
#include "presentation/UiState.h"
#include "presentation/imgui/ImGuiConversions.h"

namespace
{
    bool has_panel(const std::shared_ptr<const ta::ui::ConfigUiSnapshot>& snapshot, const char* id)
    {
        if (!snapshot)
            return false;
        return std::ranges::any_of(snapshot->panels, [id](const ta::ui::ConfigPanelSnapshot& panel)
        {
            return panel.id == id;
        });
    }
}

namespace ta::presentation
{
    void ConfigCommandSubmitter::operator()(ConfigCommand command) const
    {
        if (!commands_)
            return;
        if (command.type == ConfigCommandType::SetValue)
            command.trace_id = 0;
        commands_->submit_config_command(std::move(command));
    }

    MenuContext build_menu_context(
        const UiShellSnapshot& model,
        MenuPorts& ports,
        UiState& state)
    {
        MenuContext context{};
        context.valid = model.valid;
        context.in_raid = model.in_raid;
        context.config = model.config;
        context.diagnostics = model.diagnostics;
        context.has_aimbot = has_panel(model.config, "aimbot");
        context.menu_key = model.menu_key;
        context.key_input = &ports.key_input;
        context.submit_config = ConfigCommandSubmitter(&ports.commands, &ports.key_input);
        context.items.in_raid = model.in_raid;
        context.items.submit_config = context.submit_config;
        context.items.commands = &ports.item_commands;
        context.quests.in_raid = model.in_raid;
        context.quests.queries = &ports.quest_queries;
        context.quests.commands = &ports.quest_commands;

        const std::uint64_t item_navigation_revision = ports.item_queries.navigation_revision();
        if (item_navigation_revision != state.item_navigation_revision)
        {
            state.item_navigation_revision = item_navigation_revision;
            state.selected_page = ta::presentation::pages::PageId::Items;
            state.open = true;
        }

        if (state.open && state.selected_page == ta::presentation::pages::PageId::Items)
        {
            context.items.catalog = ports.item_queries.catalog();
        }

        if (const auto watermark = ports.watermark_queries.snapshot())
        {
            context.watermark = {
                watermark->enabled,
                watermark->text,
                ta::presentation::imgui::to_imgui(watermark->color),
                watermark->font_size
            };
        }

        const auto esp_settings = ports.esp_queries.settings();
        const auto esp_world = ports.esp_queries.world();
        const auto camera = ports.esp_queries.camera();
        if (esp_settings && esp_world && camera)
            context.esp = ta::presentation::overlays::esp::build_esp_overlay(*esp_settings, *esp_world, *camera);

        return context;
    }
}
