#include "presentation/theme/MenuTheme.h"

#include <algorithm>

#include <imgui.h>

#include "presentation/runtime/Viewport.h"

namespace ta::presentation::theme
{
    ImVec4 with_alpha(ImVec4 color, const float alpha)
    {
        color.w = alpha;
        return color;
    }

    float scaled(const float value) noexcept
    {
        return value * ta::presentation::runtime::scale_factor();
    }

    UiMetrics ui_metrics() noexcept
    {
        const float scale = ta::presentation::runtime::scale_factor();
        UiMetrics metrics{};
        metrics.scale = scale;
        metrics.spacing_xs *= scale;
        metrics.spacing_sm *= scale;
        metrics.spacing_md *= scale;
        metrics.spacing_lg *= scale;
        metrics.form_stack_width *= scale;
        metrics.column_min_width *= scale;
        metrics.sidebar_min_width *= scale;
        metrics.sidebar_max_width *= scale;
        metrics.window_min_width *= scale;
        metrics.window_min_height *= scale;
        metrics.window_width *= scale;
        metrics.window_height *= scale;
        return metrics;
    }

    bool compact_for_width(const float available_width, const float minimum_unscaled) noexcept
    {
        return available_width < scaled(minimum_unscaled);
    }

    void apply_compact_metrics()
    {
        const UiMetrics metrics = ui_metrics();
        ImGuiStyle& style = ImGui::GetStyle();
        style.WindowPadding = ImVec2(metrics.spacing_sm, metrics.spacing_sm);
        style.FramePadding = ImVec2(scaled(6.0f), scaled(3.0f));
        style.CellPadding = ImVec2(scaled(5.0f), scaled(2.0f));
        style.ItemSpacing = ImVec2(metrics.spacing_sm, scaled(2.0f));
        style.ItemInnerSpacing = ImVec2(scaled(4.0f), scaled(2.0f));
        style.IndentSpacing = scaled(18.0f);
        style.ScrollbarSize = scaled(14.0f);
        style.GrabMinSize = scaled(10.0f);
    }

    void apply_modern_style()
    {
        ImGuiStyle& style = ImGui::GetStyle();
        style.WindowRounding = scaled(9.0f);
        style.ChildRounding = scaled(7.0f);
        style.FrameRounding = scaled(5.0f);
        style.PopupRounding = scaled(7.0f);
        style.ScrollbarRounding = scaled(7.0f);
        style.GrabRounding = scaled(5.0f);
        style.WindowBorderSize = scaled(1.0f);
        style.ChildBorderSize = scaled(1.0f);
        style.FrameBorderSize = 0.0f;

        ImVec4* colors = style.Colors;
        colors[ImGuiCol_Text] = palette::text;
        colors[ImGuiCol_TextDisabled] = palette::muted;
        colors[ImGuiCol_WindowBg] = palette::bg;
        colors[ImGuiCol_ChildBg] = with_alpha(palette::surface, 0.42f);
        colors[ImGuiCol_PopupBg] = palette::surface;
        colors[ImGuiCol_Border] = with_alpha(palette::line, 0.70f);
        colors[ImGuiCol_FrameBg] = palette::surface2;
        colors[ImGuiCol_FrameBgHovered] = with_alpha(palette::accent, 0.22f);
        colors[ImGuiCol_FrameBgActive] = with_alpha(palette::accent, 0.35f);
        colors[ImGuiCol_CheckMark] = palette::success;
        colors[ImGuiCol_SliderGrab] = palette::accent;
        colors[ImGuiCol_SliderGrabActive] = palette::accent2;
        colors[ImGuiCol_Button] = palette::surface2;
        colors[ImGuiCol_ButtonHovered] = with_alpha(palette::accent, 0.55f);
        colors[ImGuiCol_ButtonActive] = palette::accent;
        colors[ImGuiCol_Header] = with_alpha(palette::accent, 0.18f);
        colors[ImGuiCol_HeaderHovered] = with_alpha(palette::accent, 0.34f);
        colors[ImGuiCol_HeaderActive] = with_alpha(palette::accent, 0.50f);
        colors[ImGuiCol_Separator] = with_alpha(palette::line, 0.75f);
        colors[ImGuiCol_SeparatorHovered] = palette::accent;
        colors[ImGuiCol_SeparatorActive] = palette::accent2;
        colors[ImGuiCol_ScrollbarBg] = palette::bg;
        colors[ImGuiCol_ScrollbarGrab] = palette::surface2;
        colors[ImGuiCol_ScrollbarGrabHovered] = palette::line;
        colors[ImGuiCol_ScrollbarGrabActive] = palette::accent;
        colors[ImGuiCol_TableHeaderBg] = palette::surface2;
        colors[ImGuiCol_TableBorderStrong] = palette::line;
        colors[ImGuiCol_TableBorderLight] = with_alpha(palette::line, 0.45f);
        colors[ImGuiCol_TableRowBgAlt] = with_alpha(palette::surface2, 0.32f);
        colors[ImGuiCol_Tab] = palette::surface;
        colors[ImGuiCol_TabHovered] = palette::surface2;
        colors[ImGuiCol_TabActive] = palette::accent;
        colors[ImGuiCol_NavHighlight] = palette::accent;
        colors[ImGuiCol_NavWindowingHighlight] = with_alpha(palette::accent, 0.70f);
    }
}
