#pragma once

#include <SDL3/SDL.h>  // Para SDL_Keycode, Uint32, Uint64

#include <cstdint>  // Para uint8_t
#include <memory>   // Para unique_ptr
#include <vector>   // Para vector

#include "color.h"        // Para Color
#include "param.h"        // Para Param, ParamIntro, param
#include "path_sprite.h"  // Para PathSprite
#include "tiled_bg.h"     // Para TiledBG
#include "writer.h"       // Para Writer

/*
        Esta clase gestiona un estado del programa. Se encarga de mostrar la secuencia
        de introducción.
*/

// Clase Intro
class Intro {
    public:
        // --- Constructor y destructor ---
        Intro();
        ~Intro() = default;

        // --- Bucle principal ---
        void run();

    private:
        // --- Estados internos ---
        enum class IntroState {
            SCENES,
            POST,
        };

        enum class IntroPostState {
            STOP_BG,
            END,
        };

        // --- Objetos ---
        std::vector<std::unique_ptr<PathSprite>> card_sprites_;    // Vector con los sprites inteligentes para los dibujos de la intro
        std::vector<std::unique_ptr<PathSprite>> shadow_sprites_;  // Vector con los sprites inteligentes para las sombras
        std::vector<std::unique_ptr<Writer>> texts_;               // Textos de la intro
        std::unique_ptr<TiledBG> tiled_bg_;                        // Fondo en mosaico
        // std::unique_ptr<Sprite> shadow_square_for_text_; // Sprite

        // --- Variables ---
        Uint64 ticks_ = 0;                                     // Contador de ticks para ajustar la velocidad del programa
        int scene_ = 0;                                        // Indica qué escena está activa
        IntroState state_ = IntroState::SCENES;                // Estado principal de la intro
        IntroPostState post_state_ = IntroPostState::STOP_BG;  // Estado POST
        Uint32 state_start_time_;                              // Tiempo de inicio del estado actual
        Color bg_color_ = param.intro.bg_color;                // Color de fondo

        // --- Métodos internos ---
        void update();                 // Actualiza las variables del objeto
        void render();                 // Dibuja el objeto en pantalla
        void checkEvents();            // Comprueba los eventos
        static void checkInput();      // Comprueba las entradas
        void updateScenes();           // Actualiza las escenas de la intro
        void initSprites();            // Inicializa las imágenes
        void initTexts();              // Inicializa los textos
        void updateSprites();          // Actualiza los sprites
        void updateTexts();            // Actualiza los textos
        void renderSprites();          // Dibuja los sprites
        void renderTexts();            // Dibuja los textos
        static void renderTextRect();  // Dibuja el rectangulo de fondo del texto;
        void updatePostState();        // Actualiza el estado POST
#ifdef _DEBUG
        static void adjustColorComponent(uint8_t& component, bool increase);
        static void adjustAllColorComponents(Color& color, bool increase);
        static void handleDebugColorKeys(SDL_Keycode key, Color& color);
        static void printColorDebugInfo(const Color& color);
#endif

        // --- Métodos para manejar cada escena individualmente ---
        void updateScene0();
        void updateScene1();
        void updateScene2();
        void updateScene3();
        void updateScene4();
        void updateScene5();

        // --- Métodos auxiliares para reducir duplicación de código ---
        void enableCardAndShadow(int index);
        void switchText(int from_index, int to_index);
};
