#pragma once

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

#include "utils/color.hpp"  // Para Color

// --- Enums ---
enum class TiledBGMode : int {  // Modos de funcionamiento para el tileado de fondo
    CIRCLE = 0,
    DIAGONAL = 1,
    RANDOM = 2,
    STATIC = 3,
};

// --- Clase TiledBG: dibuja un tileado de fondo con efectos de movimiento ---
// Esta clase se sirve de una textura "canvas", que rellena con los tiles.
// El rectángulo "window" recorre la textura de diferentes formas para generar el efecto de movimiento.
class TiledBG {
   public:
    // --- Constructores y destructor ---
    TiledBG(SDL_FRect pos, TiledBGMode mode);
    ~TiledBG();

    // --- Métodos principales ---
    void render();                  // Pinta la clase en pantalla
    void update(float delta_time);  // Actualiza la lógica de la clase

    // --- Configuración ---
    void setSpeed(float speed) { speed_ = speed; }                                              // Establece la velocidad
    void changeSpeedTo(float target_speed, float duration_s);                                   // Cambia la velocidad gradualmente en X segundos
    void stopGracefully() { stopping_ = true; }                                                 // Detiene el desplazamiento de forma ordenada
    void setColor(Color color) { SDL_SetTextureColorMod(canvas_, color.r, color.g, color.b); }  // Cambia el color de la textura

    // --- Getters ---
    [[nodiscard]] auto isStopped() const -> bool { return speed_ == 0.0F; }         // Indica si está parado
    [[nodiscard]] auto isChangingSpeed() const -> bool { return changing_speed_; }  // Indica si está cambiando velocidad gradualmente

   private:
    // --- Constantes ---
    static constexpr int TILE_WIDTH = 64;                  // Ancho del tile
    static constexpr int TILE_HEIGHT = 64;                 // Alto del tile
    static constexpr float STOP_THRESHOLD_FACTOR = 20.0F;  // Factor para umbral de parada
    static constexpr float DECELERATION_FACTOR = 1.05F;    // Factor de desaceleración
    static constexpr float MIN_SPEED = 0.1F;               // Velocidad mínima

    // --- Objetos y punteros ---
    SDL_Renderer* renderer_;  // El renderizador de la ventana
    SDL_Texture* canvas_;     // Textura donde dibujar el fondo formado por tiles

    // --- Variables de estado ---
    SDL_FRect pos_;          // Posición y tamaño del mosaico
    SDL_FRect window_;       // Ventana visible para la textura de fondo del título
    TiledBGMode mode_;       // Tipo de movimiento del mosaico
    float desp_ = 0.0F;      // Desplazamiento aplicado
    float speed_ = 1.0F;     // Incremento que se añade al desplazamiento a cada bucle
    bool stopping_ = false;  // Indica si se está deteniendo

    // --- Variables para cambio gradual de velocidad ---
    bool changing_speed_ = false;     // Indica si está cambiando velocidad gradualmente
    float initial_speed_ = 0.0F;      // Velocidad inicial del cambio
    float target_speed_ = 0.0F;       // Velocidad objetivo del cambio
    float change_duration_s_ = 0.0F;  // Duración total del cambio en segundos
    float change_timer_s_ = 0.0F;     // Tiempo transcurrido del cambio

    // --- Métodos internos ---
    void fillTexture();                                                  // Rellena la textura con el contenido
    void updateDesp(float delta_time) { desp_ += speed_ * delta_time; }  // Actualiza el desplazamiento (time-based)
    void updateStop(float delta_time);                                   // Detiene el desplazamiento de forma ordenada (time-based)
    void updateSpeedChange(float delta_time);                            // Actualiza el cambio gradual de velocidad (time-based)
};