// MenuState.h
#pragma once
#include "State.h"

#include <cstdint>
#include <memory>
#include <string>

class NetSession;

class MenuState : public State {
public:
    MenuState(StateContext& ctx);
    void onEnter() override;
    void onExit() override;
    void handleEvent(const SDL_Event& e) override;
    void update(double frameMs) override;
    void render(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP) override;
    // When false, the main PLAY button is not drawn by `render()` and can be
    // rendered separately with `renderMainButtonTop` (useful for layer ordering).
    bool drawMainButtonNormally = true;
    // Draw only the main PLAY button on top of other layers (expects logical coords).
    void renderMainButtonTop(SDL_Renderer* renderer, float logicalScale, SDL_Rect logicalVP);
    // Show or hide the inline HELP panel (menu-style)
    void showHelpPanel(bool show);
    // Show or hide the inline ABOUT panel (menu-style)
    void showAboutPanel(bool show);

    // Show or hide the inline COOPERATE setup panel (2P vs AI).
    // If `resumeMusic` is false when hiding, the menu music will not be restarted.
    void showCoopSetupPanel(bool show, bool resumeMusic = true);
    
private:
    int selectedButton = 0; // 0=PLAY,1=COOPERATE,2=CHALLENGE,3=LEVEL,4=OPTIONS,5=HELP,6=ABOUT,7=EXIT
    
    // Button icons (optional - will use text if nullptr)
    SDL_Texture* playIcon = nullptr;
    SDL_Texture* levelIcon = nullptr;
    SDL_Texture* optionsIcon = nullptr;
    SDL_Texture* exitIcon = nullptr;
    SDL_Texture* helpIcon = nullptr;
    
    // Options panel animation state
    bool optionsVisible = false;
    bool optionsAnimating = false;
    double optionsTransition = 0.0; // 0..1
    double optionsTransitionDurationMs = 400.0;
    int optionsDirection = 1; // 1 show, -1 hide
    // Which row in the inline options panel is currently selected (0..4)
    int optionsSelectedRow = 0;
    // Inline level selector HUD state
    bool levelPanelVisible = false;
    bool levelPanelAnimating = false;
    double levelTransition = 0.0; // 0..1
    double levelTransitionDurationMs = 400.0;
    int levelDirection = 1; // 1 show, -1 hide
    int levelHovered = -1; // hovered cell
    int levelSelected = 0; // current selected level
    // Cache logical viewport/scale for input conversion when needed
    float lastLogicalScale = 1.0f;
    SDL_Rect lastLogicalVP{0,0,0,0};
    // Animated highlight position (world/logical coordinates)
    double levelHighlightX = 0.0;
    double levelHighlightY = 0.0;
    bool levelHighlightInitialized = false;
    // Highlight tuning parameters
    double levelHighlightSpeed = 0.018; // smoothing constant - higher = snappier
    double levelHighlightGlowAlpha = 0.70; // 0..1 base glow alpha
    int levelHighlightThickness = 3; // inner outline thickness (px)
    SDL_Color levelHighlightColor = SDL_Color{80, 200, 255, 200};
    // Button pulsing/fade parameters (used for PLAY emphasis)
    double buttonGroupAlpha = 1.0; // base alpha for the whole group (kept stable)
    double buttonPulseAlpha = 1.0; // pulsing alpha (0..1), applied to PLAY only
    double buttonPulseTime = 0.0;  // accumulator in ms
    bool   buttonPulseEnabled = true; // enable/disable pulsing
    double buttonPulseSpeed = 1.0;  // multiplier for pulse frequency
    double buttonPulseMinAlpha = 0.60; // minimum alpha during pulse
    double buttonPulseMaxAlpha = 1.00; // maximum alpha during pulse
    // Pulse easing mode: 0=sin,1=triangle,2=exponential
    int    buttonPulseEasing = 1;
    // Short bright flash when navigating buttons
    double buttonFlash = 0.0; // transient flash amount (0..1)
    double buttonFlashAmount = 0.45; // how much flash adds to group alpha
    double buttonFlashDecay = 0.0025; // linear decay per ms
    // Exit confirmation HUD state (inline HUD like Options/Level)
    bool exitPanelVisible = false;
    bool exitPanelAnimating = false;
    double exitTransition = 0.0; // 0..1
    double exitTransitionDurationMs = 360.0;
    int exitDirection = 1; // 1 show, -1 hide
    int exitSelectedButton = 0; // 0 = YES (quit), 1 = NO (cancel)
    double exitScroll = 0.0; // vertical scroll offset for content
    // Help submenu (inline HUD like Options/Exit)
    bool helpPanelVisible = false;
    bool helpPanelAnimating = false;
    double helpTransition = 0.0; // 0..1
    double helpTransitionDurationMs = 360.0;
    int helpDirection = 1; // 1 show, -1 hide
    double helpScroll = 0.0; // vertical scroll offset for content

    // About submenu (inline HUD like Help)
    bool aboutPanelVisible = false;
    bool aboutPanelAnimating = false;
    double aboutTransition = 0.0; // 0..1
    double aboutTransitionDurationMs = 360.0;
    int aboutDirection = 1; // 1 show, -1 hide

    // Coop setup panel (inline HUD like Exit/Help)
    bool coopSetupVisible = false;
    bool coopSetupAnimating = false;
    double coopSetupTransition = 0.0; // 0..1
    double coopSetupTransitionDurationMs = 320.0;
    int coopSetupDirection = 1; // 1 show, -1 hide
    // 0 = Local co-op (2 players), 1 = AI partner, 2 = 2 player (network)
    int coopSetupSelected = 0;

    enum class CoopSetupStep {
        ChoosePartner,
        NetworkChooseRole,
        NetworkEnterAddress,
        NetworkWaiting,
    };
    CoopSetupStep coopSetupStep = CoopSetupStep::ChoosePartner;

    // Network sub-flow state (only used when coopSetupSelected == 2)
    int coopNetworkRoleSelected = 0; // 0 = host, 1 = join
    std::string coopNetworkBindAddress = "0.0.0.0";
    std::string coopNetworkJoinAddress = "127.0.0.1";
    uint16_t coopNetworkPort = 7777;
    bool coopNetworkHandshakeSent = false;
    std::string coopNetworkStatusText;
    std::unique_ptr<NetSession> coopNetworkSession;

    SDL_FRect coopSetupBtnRects[3]{};
    bool coopSetupRectsValid = false;
    // Optional cooperative info image shown when coop setup panel is active
    SDL_Texture* coopInfoTexture = nullptr;
    int coopInfoTexW = 0;
    int coopInfoTexH = 0;
};
