#pragma once

#include <SDL3/SDL_rect.h>   // Para SDL_FRect, SDL_FPoint
#include <SDL3/SDL_render.h> // Para SDL_Texture, SDL_Renderer
#include <stddef.h>          // Para size_t
#include <memory>            // Para unique_ptr, shared_ptr
#include <vector>            // Para vector
#include "utils.h"           // Para Color
class MovingSprite;
class Sprite;
class Texture;

/*
    Esta clase gestiona el fondo que aparece en la sección jugable.

    Usa una textura compuesta y una capa superior con un color sólido cuya opacidad es ajustable.
    Su área total está definida por "rect", pero solo se pinta la región "srcRect" en la pantalla en "dstRect".

    Métodos clave:
    - setCloudsSpeed(float value) -> Define la velocidad de las nubes
    - setGradientNumber(int value) -> Ajusta el índice del color de cielo
    - setTransition(float value) -> Configura la transición entre texturas
    - setColor(Color color) -> Aplica un color de atenuación
    - setAlpha(int alpha) -> Ajusta la transparencia de la capa de atenuación
*/
class Background
{
public:
  // Constructor y Destructor
  Background();
  ~Background();

  // Actualización y renderizado
  void update(); // Actualiza la lógica del objeto
  void render(); // Dibuja el objeto

  // Configuración de posición
  void setPos(SDL_FRect pos); // Establece la posición del objeto

  // Configuración de animaciones y efectos
  void setCloudsSpeed(float value);  // Ajusta la velocidad de desplazamiento de las nubes
  void setGradientNumber(int value); // Establece el degradado de fondo a usar
  void setTransition(float value);   // Ajusta la transición entre texturas de fondo

  // Configuración de efectos visuales
  void setColor(Color color); // Establece el color de atenuación
  void setAlpha(int alpha);   // Ajusta la transparencia del fondo

  // Configuración del sol y la luna
  void setSunProgression(float progress);  // Establece la posición del sol
  void setMoonProgression(float progress); // Establece la posición de la luna

private:
  // Objetos y punteros
  SDL_Renderer *renderer_; // Renderizador de la ventana

  // Texturas
  std::shared_ptr<Texture> buildings_texture_;
  std::shared_ptr<Texture> top_clouds_texture_;
  std::shared_ptr<Texture> bottom_clouds_texture_;
  std::shared_ptr<Texture> grass_texture_;
  std::shared_ptr<Texture> gradients_texture_;
  std::shared_ptr<Texture> sun_texture_;
  std::shared_ptr<Texture> moon_texture_;

  // Sprites
  std::unique_ptr<MovingSprite> top_clouds_sprite_a_;
  std::unique_ptr<MovingSprite> top_clouds_sprite_b_;
  std::unique_ptr<MovingSprite> bottom_clouds_sprite_a_;
  std::unique_ptr<MovingSprite> bottom_clouds_sprite_b_;
  std::unique_ptr<Sprite> buildings_sprite_;
  std::unique_ptr<Sprite> gradient_sprite_;
  std::unique_ptr<Sprite> grass_sprite_;
  std::unique_ptr<Sprite> sun_sprite_;
  std::unique_ptr<Sprite> moon_sprite_;

  // Buffers de renderizado
  SDL_Texture *canvas_;        // Textura para componer el fondo
  SDL_Texture *color_texture_; // Textura para atenuar el fondo

  // Variables de control
  SDL_FRect gradient_rect_[4];
  SDL_FRect top_clouds_rect_[4];
  SDL_FRect bottom_clouds_rect_[4];
  int gradient_number_ = 0;
  int alpha_ = 0;
  float clouds_speed_ = 0;
  float transition_ = 0;
  int counter_ = 0;
  SDL_FRect rect_;
  SDL_FRect src_rect_;
  SDL_FRect dst_rect_;
  int base_;
  Color attenuate_color_;
  int alpha_color_text_;
  int alpha_color_text_temp_;
  std::vector<SDL_FPoint> sun_path_;
  std::vector<SDL_FPoint> moon_path_;
  size_t sun_index_ = 0;
  size_t moon_index_ = 0;

  // Métodos internos
  void renderGradient();          // Dibuja el gradiente de fondo
  void renderTopClouds();         // Dibuja las nubes superiores
  void renderBottomClouds();      // Dibuja las nubes inferiores
  void fillCanvas();              // Compone todos los elementos en la textura
  void updateAlphaColorTexture(); // Actualiza el alpha de la textura de atenuación
  void updateClouds();            // Actualiza el movimiento de las nubes
  void createSunPath();           // Precalcula el recorrido del sol
  void createMoonPath();          // Precalcula el recorrido de la luna
};
