#include "ui/BottomMenu.h"

#include <algorithm>
#include <cmath>
#include <cstdio>

#include "graphics/renderers/UIRenderer.h"
#include "graphics/Font.h"

namespace ui {

static bool pointInRect(const SDL_FRect& r, float x, float y) {
    return x >= r.x && x <= (r.x + r.w) && y >= r.y && y <= (r.y + r.h);
}

BottomMenu buildBottomMenu(const MenuLayoutParams& params, int startLevel, bool coopVsAI) {
    BottomMenu menu{};

    auto rects = computeMenuButtonRects(params);

    char levelBtnText[32];
    std::snprintf(levelBtnText, sizeof(levelBtnText), "LEVEL %d", startLevel);

    menu.buttons[0] = Button{ BottomMenuItem::Play, rects[0], "PLAY", false };
    // Always show a neutral "COOPERATE" label (remove per-mode suffixes)
    menu.buttons[1] = Button{ BottomMenuItem::Cooperate, rects[1], "COOPERATE", false };
    menu.buttons[2] = Button{ BottomMenuItem::Challenge, rects[2], "CHALLENGE", false };
    menu.buttons[3] = Button{ BottomMenuItem::Level, rects[3], levelBtnText, true };
    menu.buttons[4] = Button{ BottomMenuItem::Options, rects[4], "OPTIONS", true };
    menu.buttons[5] = Button{ BottomMenuItem::Help, rects[5], "HELP", true };
    menu.buttons[6] = Button{ BottomMenuItem::About, rects[6], "ABOUT", true };
    menu.buttons[7] = Button{ BottomMenuItem::Exit, rects[7], "EXIT", true };

    return menu;
}

void renderBottomMenu(SDL_Renderer* renderer,
                      FontAtlas* font,
                      const BottomMenu& menu,
                      int hoveredIndex,
                      int selectedIndex,
                      double baseAlphaMul,
                      double flashAddMul) {
    if (!renderer || !font) return;

    const double baseMul = std::clamp(baseAlphaMul, 0.0, 1.0);
    const double flashMul = flashAddMul;

    const int focusIndex = (hoveredIndex != -1) ? hoveredIndex : selectedIndex;

    for (int i = 0; i < MENU_BTN_COUNT; ++i) {
        const Button& b = menu.buttons[i];
        const SDL_FRect& r = b.rect;

        float cx = r.x + r.w * 0.5f;
        float cy = r.y + r.h * 0.5f;

        bool isHovered = (hoveredIndex == i);
        bool isSelected = (selectedIndex == i);

        // Requested behavior: flash only the PLAY button, and only when it's the active/focused item.
        const bool playIsActive = (i == 0) && (focusIndex == 0);
        const double aMul = std::clamp(baseMul + (playIsActive ? flashMul : 0.0), 0.0, 1.0);

        if (!b.textOnly) {
            const bool isPlay = (i == 0);
            const bool isCoop = (i == 1);
            const bool isChallenge = (i == 2);
            SDL_Color bgCol{ 18, 22, 28, static_cast<Uint8>(std::round(180.0 * aMul)) };
            SDL_Color bdCol{ 255, 200, 70, static_cast<Uint8>(std::round(220.0 * aMul)) };
            if (isCoop) {
                // Cooperative mode gets a cyan/magenta accent to separate from Endless/Challenge
                bgCol = SDL_Color{ 22, 30, 40, static_cast<Uint8>(std::round(190.0 * aMul)) };
                bdCol = SDL_Color{ 160, 210, 255, static_cast<Uint8>(std::round(230.0 * aMul)) };
            } else if (isChallenge) {
                // Give Challenge a teal accent to distinguish from Play
                bgCol = SDL_Color{ 18, 36, 36, static_cast<Uint8>(std::round(190.0 * aMul)) };
                bdCol = SDL_Color{ 120, 255, 220, static_cast<Uint8>(std::round(230.0 * aMul)) };
            }
            UIRenderer::drawButton(renderer, font, cx, cy, r.w, r.h,
                                   b.label, isHovered, isSelected,
                                   bgCol, bdCol, false, nullptr);
        } else {
            SDL_Color bgCol{ 20, 30, 42, static_cast<Uint8>(std::round(160.0 * aMul)) };
            SDL_Color bdCol{ 120, 220, 255, static_cast<Uint8>(std::round(200.0 * aMul)) };
            UIRenderer::drawButton(renderer, font, cx, cy, r.w, r.h,
                                   b.label, isHovered, isSelected,
                                   bgCol, bdCol, true, nullptr);
        }
    }

    // '+' separators between the bottom HUD buttons (indices 3..last)
    {
        SDL_BlendMode prevBlend = SDL_BLENDMODE_NONE;
        SDL_GetRenderDrawBlendMode(renderer, &prevBlend);
        SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
        SDL_SetRenderDrawColor(renderer, 120, 220, 255, static_cast<Uint8>(std::round(180.0 * baseMul)));

        const int firstSmall = 3;
        const int lastSmall = MENU_BTN_COUNT - 1;
        float y = menu.buttons[firstSmall].rect.y + menu.buttons[firstSmall].rect.h * 0.5f;
        for (int i = firstSmall; i < lastSmall; ++i) {
            float x = (menu.buttons[i].rect.x + menu.buttons[i].rect.w + menu.buttons[i + 1].rect.x) * 0.5f;
            SDL_RenderLine(renderer, x - 4.0f, y, x + 4.0f, y);
            SDL_RenderLine(renderer, x, y - 4.0f, x, y + 4.0f);
        }

        SDL_SetRenderDrawBlendMode(renderer, prevBlend);
    }
}

BottomMenuInputResult handleBottomMenuInput(const MenuLayoutParams& params,
                                            const SDL_Event& e,
                                            float x,
                                            float y,
                                            int prevHoveredIndex,
                                            bool inputEnabled) {
    BottomMenuInputResult result{};
    result.hoveredIndex = prevHoveredIndex;

    if (!inputEnabled) {
        return result;
    }

    if (e.type == SDL_EVENT_MOUSE_MOTION) {
        result.hoveredIndex = hitTestMenuButtons(params, x, y);
        return result;
    }

    if (e.type == SDL_EVENT_MOUSE_BUTTON_DOWN && e.button.button == SDL_BUTTON_LEFT) {
        auto rects = computeMenuButtonRects(params);
        for (int i = 0; i < MENU_BTN_COUNT; ++i) {
            if (pointInRect(rects[i], x, y)) {
                result.activated = static_cast<BottomMenuItem>(i);
                result.hoveredIndex = i;
                break;
            }
        }
    }

    return result;
}

} // namespace ui
