#pragma once

#include <SDL3/SDL.h>  // Para SDL_FRect, SDL_Renderer, SDL_Texture, Uint64

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

#include "core/rendering/fade.hpp"  // for Fade
#include "utils/color.hpp"          // for Color

class Background;
class PathSprite;
class Sprite;
struct Path;

// --- Clase HiScoreTable: muestra la tabla de puntuaciones más altas ---
// Esta clase gestiona un estado del programa. Se encarga de mostrar la tabla con las puntuaciones
// más altas. Para ello utiliza un objeto que se encarga de pintar el fondo y una textura
// sobre la que escribe las puntuaciones. Esta textura se recorre modificando la ventana de vista
// para dar el efecto de que la textura se mueve sobre la pantalla.
// Para mejorar la legibilidad de los textos, el objeto que dibuja el fondo es capaz de modificar
// su atenuación.
class HiScoreTable {
   public:
    // --- Constructor y destructor ---
    HiScoreTable();
    ~HiScoreTable();

    // --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
    void iterate();                            // Ejecuta un frame
    void handleEvent(const SDL_Event& event);  // Procesa un evento

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

   private:
    // --- Constantes (en segundos) ---
    static constexpr float COUNTER_END_S = 800.0F / 60.0F;        // Tiempo final (≈13.33s)
    static constexpr float INIT_DELAY_S = 190.0F / 60.0F;         // Retraso inicial (≈3.17s)
    static constexpr float ENTRY_DELAY_S = 16.0F / 60.0F;         // Retraso entre entradas (≈0.27s)
    static constexpr float BACKGROUND_CHANGE_S = 150.0F / 60.0F;  // Tiempo cambio fondo (≈2.5s)
    static constexpr float ANIM_DURATION_S = 80.0F / 60.0F;       // Duración animación (≈1.33s)
    static constexpr float CLOUDS_SPEED = -6.0F;                  // Velocidad nubes (pixels/s)
    static constexpr float SCROLL_SPEED_PPS = 60.0F;              // Velocidad de scroll (60 pixels por segundo)

    // --- Objetos y punteros ---
    SDL_Renderer* renderer_;   // El renderizador de la ventana
    SDL_Texture* backbuffer_;  // Textura para usar como backbuffer

    std::unique_ptr<Fade> fade_;                            // Objeto para renderizar fades
    std::unique_ptr<Background> background_;                // Objeto para dibujar el fondo del juego
    std::unique_ptr<Sprite> header_;                        // Sprite con la cabecera del texto
    std::vector<std::shared_ptr<PathSprite>> entry_names_;  // Lista con los sprites de cada uno de los nombres de la tabla de records
    std::vector<Path> paths_;                               // Vector con los recorridos precalculados

    // --- Variables ---
    float elapsed_time_ = 0.0F;        // Tiempo transcurrido (segundos)
    Uint64 last_time_ = 0;             // Último timestamp para calcular delta-time
    SDL_FRect view_area_;              // Parte de la textura que se muestra en pantalla
    Fade::Mode fade_mode_;             // Modo de fade a utilizar
    Color background_fade_color_;      // Color de atenuación del fondo
    std::vector<Color> entry_colors_;  // Colores para destacar las entradas en la tabla

    // --- Flags para eventos basados en tiempo ---
    struct HiScoreFlags {
        bool background_changed = false;
        bool fade_activated = false;

        void reset() {
            background_changed = false;
            fade_activated = false;
        }
    } hiscore_flags_;

    // --- Métodos internos ---
    void update(float delta_time);                  // Actualiza las variables
    void render();                                  // Pinta en pantalla
    static void checkEvents();                      // Comprueba los eventos
    static void checkInput();                       // Comprueba las entradas
    static auto format(int number) -> std::string;  // Convierte un entero a un string con separadores de miles
    void fillTexture();                             // Dibuja los sprites en la textura
    void updateFade(float delta_time);              // Gestiona el fade
    void createSprites();                           // Crea los sprites con los textos
    void updateSprites(float delta_time);           // Actualiza las posiciones de los sprites de texto
    void initFade();                                // Inicializa el fade
    void initBackground();                          // Inicializa el fondo
    auto getEntryColor(int counter) -> Color;       // Obtiene un color del vector de colores de entradas
    void iniEntryColors();                          // Inicializa los colores de las entradas
    void glowEntryNames();                          // Hace brillar los nombres de la tabla de records
    void updateCounter();                           // Gestiona el contador
    auto calculateDeltaTime() -> float;             // Calcula el tiempo transcurrido desde el último frame
};