#pragma once

#include <SDL3/SDL.h>

#include <memory>  // Para shared_ptr
#include <string>  // Para string
#include <vector>  // Para vector

#include "utils/delta_timer.hpp"  // Para DeltaTimer
class SurfaceSprite;               // Forward declaration
class Surface;                     // Forward declaration
class Text;                        // Forward declaration

class Title {
    private:
        struct TitleLetter {
                char letter;   // Letra a escribir (char es más eficiente que std::string)
                float x;       // Posición en el eje x (float para precisión con delta time)
                float width;   // Ancho pre-calculado del carácter
                bool enabled;  // Solo se escriben y mueven si estan habilitadas
        };

        enum class TitleState {
            SHOW_LOADING_SCREEN,
            FADE_LOADING_SCREEN,
            SHOW_MENU
        };

        // --- Constantes de tiempo (en segundos) ---
        static constexpr float SHOW_LOADING_DURATION = 5.0F;   // Tiempo mostrando loading screen (antes 500 frames)
        static constexpr float FADE_STEP_INTERVAL = 0.033F;    // Intervalo entre pasos de fade (antes cada 4 frames)
        static constexpr float AUTO_CREDITS_TIMEOUT = 22.0F;   // Timeout para ir a créditos (antes 2200 frames)
        static constexpr float MARQUEE_SPEED = 100.0F;         // Velocidad de marquesina (pixels/segundo)
        static constexpr float CHEEVOS_SCROLL_SPEED = 120.0F;  // Velocidad de scroll de logros (pixels/segundo)

        // --- Constantes de marquesina ---
        static constexpr float MARQUEE_START_X = 256.0F;       // Posición inicial (ancho pantalla)
        static constexpr float MARQUEE_EXIT_X = -10.0F;        // Cuando desaparece de pantalla
        static constexpr float MARQUEE_Y = 184.0F;             // Posición Y
        static constexpr float MARQUEE_LETTER_SPACING = 1.0F;  // Espaciado entre letras

        // Objetos y punteros
        std::shared_ptr<Surface> title_logo_surface_;           // Textura con los graficos
        std::shared_ptr<SurfaceSprite> title_logo_sprite_;      // SSprite para manejar la surface
        std::shared_ptr<Surface> loading_screen_surface_;       // Surface con los gráficos de la pantalla de carga
        std::shared_ptr<SurfaceSprite> loading_screen_sprite_;  // SSprite con los gráficos de la pantalla de carga
        std::shared_ptr<Surface> bg_surface_;                   // Textura para dibujar el fondo de la pantalla
        std::shared_ptr<Surface> cheevos_surface_;              // Textura con la lista de logros
        std::shared_ptr<SurfaceSprite> cheevos_sprite_;         // SSprite para manejar la surface con la lista de logros

        // --- Variables de estado ---
        std::unique_ptr<DeltaTimer> delta_timer_;    // Timer para delta time
        std::shared_ptr<Text> marquee_text_;         // Cache del texto para marquesina
        std::string long_text_;                      // Texto que aparece en la parte inferior del titulo
        std::vector<TitleLetter> letters_;           // Vector con las letras de la marquesina
        int first_active_letter_;                    // Primera letra activa (optimización)
        int last_active_letter_;                     // Última letra activa (optimización)
        bool show_cheevos_ = false;                  // Indica si se muestra por pantalla el listado de logros
        SDL_FRect cheevos_surface_view_;             // Zona visible de la surface con el listado de logros
        TitleState state_;                           // Estado en el que se encuentra el bucle principal
        float state_time_;                           // Tiempo acumulado en el estado actual
        float fade_accumulator_;                     // Acumulador para controlar el fade por tiempo
        float current_delta_;                        // Delta time del frame actual

        // --- Funciones ---
        void update();                                // Actualiza las variables
        void render();                                // Dibuja en pantalla
        void checkEvents();                           // Comprueba el manejador de eventos
        void checkInput();                            // Comprueba las entradas
        void updateState(float delta_time);           // Actualiza el estado actual
        void transitionToState(TitleState new_state);  // Transiciona a un nuevo estado
        void initMarquee();                           // Inicializa la marquesina
        void updateMarquee(float delta_time);         // Actualiza la marquesina (time-based)
        void renderMarquee();                         // Dibuja la marquesina
        void moveCheevosList(int direction, float delta_time);  // Desplaza la lista de logros (time-based)

        // Rellena la surface de fondo con todos los gráficos
        void fillSurface();

        // Crea y rellena la surface para mostrar los logros
        void createCheevosTexture();

        // Oculta la lista de logros
        void hideCheevosList();

    public:
        // Constructor
        Title();

        // Destructor
        ~Title() = default;

        // Bucle principal
        void run();
};