#pragma once

#include <SDL3/SDL.h>

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

#include "game/scenes/scene.hpp"  // Para Scene
class AnimatedSprite;             // lines 11-11
class Surface;
class PixelReveal;
class DeltaTimer;

class Credits : public Scene {
   public:
    // --- Constructor y Destructor ---
    Credits();
    ~Credits() override;  // NOLINT(modernize-use-equals-default, performance-trivially-destructible) -- defined in .cpp for unique_ptr with forward declarations

    // --- Bucle principal (SDL3 Callback API) ---
    void iterate() override;
    void handleEvent(const SDL_Event& event) override;

   private:
    // --- Tipos anidados ---
    enum class State : std::uint8_t {
        REVEALING_TEXT,
        PAUSE_1,
        REVEALING_TEXT_2,
        PAUSE_2,
        REVEALING_TEXT_3,
        PAUSE_3,
        DISPLAYING_WITH_SHINE,
        FADING_OUT,
        EXITING
    };

    struct Captions {
        std::string label;  // Texto a escribir
        Uint8 color{0};     // Color del texto
    };

    // --- Constantes de tiempo (basado en 60 FPS) ---
    static constexpr float REVEAL_PHASE_1_DURATION = 3.733F;      // 224 frames @ 60fps
    static constexpr float PAUSE_DURATION = 1.667F;               // 100 frames @ 60fps
    static constexpr float REVEAL_PHASE_2_DURATION = 5.333F;      // 320 frames (544-224) @ 60fps
    static constexpr float REVEAL_PHASE_3_DURATION = 2.133F;      // 128 frames (672-544) @ 60fps
    static constexpr float DISPLAY_WITH_SHINE_DURATION = 7.967F;  // 478 frames (1150-672) @ 60fps
    static constexpr float FADE_OUT_DURATION = 0.833F;            // 50 frames (1200-1150) @ 60fps
    static constexpr float TOTAL_DURATION = 20.0F;                // 1200 frames @ 60fps
    static constexpr float SHINE_START_TIME = 12.833F;            // 770 frames @ 60fps
    static constexpr float FADE_OUT_START = 19.167F;              // 1150 frames @ 60fps
    static constexpr float PIXELS_PER_SECOND = 15.0F;             // Filas reveladas por segundo (REVEAL_SPEED/8*2 = 60/8*2 = 15)
    static constexpr float STEP_DURATION = 2.0F / 60.0F;          // Segundos por paso de revelado (2 frames @ 60fps)
    static constexpr int REVEAL_STEPS = 16;                       // Pasos de revelado por fila (más pasos = efecto más visible)

    // --- Métodos privados ---
    void update();                            // Actualiza las variables
    void render();                            // Dibuja en pantalla
    static void handleInput();                // Comprueba las entradas
    void updateState(float delta_time);       // Actualiza la máquina de estados
    void transitionToState(State new_state);  // Transición entre estados
    void iniTexts();                          // Inicializa los textos
    void fillTexture();                       // Escribe el texto en la textura

    // --- Variables miembro ---
    // Recursos gráficos
    std::shared_ptr<Surface> text_surface_;           // Textura para dibujar el texto
    std::unique_ptr<PixelReveal> pixel_reveal_;       // Efecto de revelado pixel a pixel
    std::shared_ptr<AnimatedSprite> shining_sprite_;  // Sprite para el brillo del corazón

    // Temporizadores y estado
    std::unique_ptr<DeltaTimer> delta_timer_;  // Temporizador delta para time-based update
    State state_{State::REVEALING_TEXT};       // Estado actual
    float state_time_{0.0F};                   // Tiempo acumulado en el estado actual
    float total_time_{0.0F};                   // Tiempo total acumulado
    float reveal_time_{0.0F};                  // Tiempo acumulado solo durante revelación (se congela en pausas)

    // Textos
    std::vector<Captions> texts_;  // Vector con los textos
};
