#pragma once

#include <SDL3/SDL.h>

#include <memory>  // Para shared_ptr
#include <string>  // Para string, basic_string
#include <utility>
#include <vector>      // Para vector
class AnimatedSprite;  // lines 10-10
class Surface;         // lines 11-11

class Scoreboard {
   public:
    // Tipos anidados
    struct Data {
        int items{0};              // Lleva la cuenta de los objetos recogidos
        int lives{0};              // Lleva la cuenta de las vidas restantes del jugador
        int rooms{0};              // Lleva la cuenta de las habitaciones visitadas
        bool music{true};          // Indica si ha de sonar la música durante el juego
        Uint8 color{0};            // Color para escribir el texto del marcador
        Uint32 ini_clock{0};       // Tiempo inicial para calcular el tiempo transcurrido
        bool jail_is_open{false};  // Indica si se puede entrar a la Jail
    };

    // Métodos públicos
    explicit Scoreboard(std::shared_ptr<Data> data);  // Constructor
    ~Scoreboard() = default;                          // Destructor
    void render();                                    // Pinta el objeto en pantalla
    void update(float delta_time);                    // Actualiza las variables del objeto
    void setPaused(bool value);                       // Pone el marcador en modo pausa
    void refreshPlayerSkin();                         // Actualiza el sprite del jugador con la skin actual
    auto getMinutes() -> int;                         // Devuelve la cantidad de minutos de juego transcurridos

   private:
    // Tipos anidados
    struct ClockData {
        int hours{0};                // Horas transcurridas
        int minutes{0};              // Minutos transcurridos
        int seconds{0};              // Segundos transcurridos
        std::string separator{":"};  // Separador para mostrar el tiempo
    };

    // Constantes de tiempo
    static constexpr float ITEMS_COLOR_BLINK_DURATION = 0.333F;  // Duración de cada estado del parpadeo (era 10 frames @ 60fps)
    static constexpr float SPRITE_WALK_CYCLE_DURATION = 0.667F;  // Duración del ciclo de caminar (era 40 frames @ 60fps)

    // Posición de los elementos del marcador (en pixels, Tile::SIZE = 8)
    static constexpr int LINE1_Y = 8;               // Fila superior (1 * Tile::SIZE)
    static constexpr int LINE2_Y = 24;              // Fila inferior (3 * Tile::SIZE)
    static constexpr int ITEMS_LABEL_X = 8;         // "TRESORS PILLATS" / "ITEMS COLLECTED"
    static constexpr int ITEMS_VALUE_X = 136;       // Valor numérico de items
    static constexpr int TIME_LABEL_X = 160;        // "HORA" / "TIME"
    static constexpr int TIME_VALUE_X = 208;        // Valor numérico del tiempo
    static constexpr int LIVES_START_X = 8;         // Primera vida (sprite)
    static constexpr int LIVES_SPACING = 16;        // Separación entre vidas
    static constexpr int MUSIC_ICON_X = 160;        // Icono de música
    static constexpr int ROOMS_LABEL_X = 176;       // "SALES" / "ROOMS"
    static constexpr int ROOMS_VALUE_X = 224;       // Valor numérico de salas
    static constexpr int CHEAT_INF_LIVES_X = 176;   // Indicador "vides inf" / "inf lives"
    static constexpr int CHEAT_INF_LIVES_Y = 34;    // Posición Y del indicador de vidas infinitas
    static constexpr int CHEAT_INVINCIBLE_X = 231;  // Indicador "inv"
    static constexpr int CHEAT_INVINCIBLE_Y = 34;   // Posición Y del indicador de invencibilidad

    // Métodos privados
    auto getTime() -> ClockData;              // Obtiene el tiempo transcurrido de partida
    void updateItemsColor(float delta_time);  // Actualiza el color de la cantidad de items recogidos
    void fillTexture();                       // Dibuja los elementos del marcador en la surface

    // Objetos y punteros
    std::shared_ptr<AnimatedSprite> player_sprite_;  // Sprite para mostrar las vidas en el marcador
    std::shared_ptr<Surface> item_surface_;          // Surface con los graficos para los elementos del marcador
    std::shared_ptr<Data> data_;                     // Contiene las variables a mostrar en el marcador
    std::shared_ptr<Surface> surface_;               // Surface donde dibujar el marcador

    // Variables de estado
    std::vector<Uint8> color_;       // Vector con los colores del objeto
    bool is_paused_{false};          // Indica si el marcador esta en modo pausa
    Uint32 paused_time_{0};          // Milisegundos que ha estado el marcador en pausa
    Uint32 paused_time_elapsed_{0};  // Tiempo acumulado en pausa
    ClockData clock_{};              // Contiene las horas, minutos y segundos transcurridos desde el inicio de la partida
    Uint8 items_color_{0};           // Color de la cantidad de items recogidos
    SDL_FRect surface_dest_{};       // Rectangulo donde dibujar la surface del marcador
    float time_accumulator_{0.0F};   // Acumulador de tiempo para animaciones
    float items_color_timer_{0.0F};  // Timer para parpadeo de color de items
};
