#include "presentation/MenuController.h"

#include "presentation/MenuRenderer.h"
#include "presentation/runtime/Viewport.h"
#include "presentation/fonts/MenuFontAtlas.h"
#include "application/messaging/PresentationState.h"
#include "foundation/diagnostics/CrashDiagnostics.h"
#include "presentation/theme/MenuTheme.h"

#include <imgui.h>

namespace ta::presentation
{
    MenuController::MenuController(MenuPorts ports,
                                   const ta::application::DisplayMetrics display_metrics) noexcept
        : ports_(ports), display_metrics_(display_metrics)
    {
    }

    bool MenuController::is_active() const noexcept
    {
        return state_.open;
    }

    void MenuController::setup(const ta::application::SystemFontPaths& system_fonts)
    {
        ImGuiIO& io = ImGui::GetIO();
        io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
        io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

        system_fonts_ = system_fonts;
        runtime::setup(display_metrics_);
        ta::application::presentation_state::menu_visible.publish(state_.open);
        fonts::setup(io, runtime::scale_factor(), system_fonts);
        ta::presentation::theme::apply_compact_metrics();
        ta::presentation::theme::apply_modern_style();
    }

    void MenuController::draw()
    {
        ta::foundation::diagnostics::crash::set_stage("ui.controller.capture-shell");
        const bool include_diagnostics =
            state_.open && state_.selected_page == ta::presentation::pages::PageId::Diagnostics;
        const ta::ui::UiShellSnapshot snapshot = ports_.read_model.capture_ui_shell(include_diagnostics);
        ta::foundation::diagnostics::crash::set_stage("ui.controller.build-context");
        const ta::presentation::MenuContext context = ta::presentation::build_menu_context(
            snapshot, ports_, state_);
        ta::foundation::diagnostics::crash::set_stage("ui.controller.render");
        MenuRenderer::draw(state_, context);
        ta::foundation::diagnostics::crash::set_stage("ui.controller.complete");
    }

    float MenuController::scale_factor() const noexcept
    {
        return runtime::scale_factor();
    }

    bool MenuController::needs_font_rebuild(const float scale_factor) const noexcept
    {
        return fonts::needs_rebuild(scale_factor);
    }

    void MenuController::rebuild_fonts(const float scale_factor)
    {
        fonts::rebuild(ImGui::GetIO(), scale_factor, system_fonts_);
    }

    void MenuController::reset_render_resources() noexcept
    {
        fonts::reset();
        system_fonts_ = {};
    }

}
