#pragma once

#include <SDL3/SDL.h>

#include <array>  // Para std::array
#include <cstdint>
#include <memory>  // Para shared_ptr
#include <string>  // Para string

#include "game/scene_manager.hpp"  // Para SceneManager::Scene
#include "utils/delta_timer.hpp"   // Para DeltaTimer
class Sprite;                      // Forward declaration
class Surface;                     // Forward declaration
class Text;                        // Forward declaration

class Title {
   public:
    // --- Constructor y Destructor ---
    Title();
    ~Title();

    // --- Frame (llamados desde Director::iterate) ---
    void update();
    void render();

   private:
    // --- Estructuras y enumeraciones ---
    enum class State : std::uint8_t {
        MAIN_MENU,
        FADE_MENU,
        POST_FADE_MENU,
    };

    // --- Constantes de tiempo (en segundos) ---
    static constexpr float FADE_STEP_INTERVAL = 0.05F;           // Intervalo entre pasos de fade (antes cada 4 frames)
    static constexpr float POST_FADE_DELAY = 1.0F;               // Delay después del fade (pantalla en negro)
    static constexpr float KEYBOARD_REMAP_DISPLAY_DELAY = 2.0F;  // Tiempo mostrando teclas definidas antes de guardar

    // --- Constantes de layout del menú ---
    static constexpr int MENU_ZONE_Y = 73;        // Coordenada Y de la zona de menú
    static constexpr int MENU_ZONE_HEIGHT = 102;  // Alto de la zona de menú
    // --- Métodos ---
    void handleEvents();                                                   // Comprueba el manejador de eventos
    void handleMainMenuKeyPress(SDL_Keycode key);                          // Maneja las teclas del menu principal
    void handleInput(float delta_time);                                    // Comprueba las entradas
    void updateState(float delta_time);                                    // Actualiza el estado actual
    void transitionToState(State new_state);                               // Transiciona a un nuevo estado
    void updateMainMenu(float delta_time);                                 // Actualiza MAIN_MENU
    void updateFadeMenu(float delta_time);                                 // Actualiza FADE_MENU
    void updatePostFadeMenu(float delta_time);                             // Actualiza POST_FADE_MENU
    void renderGameLogo();                                                 // Dibuja el logo con el titulo del juego
    void renderMainMenu();                                                 // Dibuja el menu principal
    void renderKeyboardRemap() const;                                      // Dibuja la pantalla de redefinir teclado
    void renderJoystickRemap() const;                                      // Dibuja la pantalla de redefinir joystick
    void handleKeyboardRemap(const SDL_Event& event);                      // Maneja la captura de teclas
    void handleJoystickRemap(const SDL_Event& event);                      // Maneja la captura de botones del gamepad
    static auto isKeyValid(SDL_Scancode scancode) -> bool;                 // Valida si una tecla es permitida
    auto isKeyDuplicate(SDL_Scancode scancode, int current_step) -> bool;  // Valida si una tecla esta duplicada
    auto isButtonDuplicate(int button, int current_step) -> bool;          // Valida si un boton esta duplicado
    void applyKeyboardRemap();                                             // Aplica y guarda las teclas redefinidas
    void applyJoystickRemap();                                             // Aplica y guarda los botones del gamepad redefinidos
    static auto getButtonName(int button) -> std::string;                  // Retorna el nombre amigable del boton del gamepad
    void fillTitleSurface();                                               // Dibuja los elementos en la surface

    // --- Variables miembro ---
    // Objetos y punteros
    std::shared_ptr<Surface> game_logo_surface_;  // Textura con los graficos
    std::unique_ptr<Sprite> game_logo_sprite_;    // SSprite para manejar la surface
    std::shared_ptr<Surface> title_surface_;      // Surface donde se dibuja toda la clase
    std::unique_ptr<DeltaTimer> delta_timer_;     // Timer para delta time
    std::shared_ptr<Text> menu_text_;             // Texto para los menus

    // Variables de estado general
    State state_;                                                // Estado en el que se encuentra el bucle principal
    float state_time_{0.0F};                                     // Tiempo acumulado en el estado actual
    float fade_accumulator_{0.0F};                               // Acumulador para controlar el fade por tiempo
    SceneManager::Scene exit_scene_{SceneManager::Scene::GAME};  // Escena de destino al salir del título

    // Variables para redefinir controles
    bool is_remapping_keyboard_{false};      // True si estamos redefiniendo teclado
    bool is_remapping_joystick_{false};      // True si estamos redefiniendo joystick
    int remap_step_{0};                      // Paso actual en la redefinicion (0=LEFT, 1=RIGHT, 2=JUMP)
    std::array<SDL_Scancode, 3> temp_keys_;  // Almacenamiento temporal de teclas capturadas
    std::array<int, 3> temp_buttons_;        // Almacenamiento temporal de botones de gamepad capturados
    std::string remap_error_message_;        // Mensaje de error si la tecla/boton es invalido
    float axis_cooldown_{0.0F};              // Cooldown para evitar múltiples capturas de ejes
    bool remap_completed_{false};            // True cuando se completa el remap (mostrar antes de guardar)
};