#pragma once

#include <SDL3/SDL_rect.h>
#include <memory>
#include <string>
#include <vector>

#include "moving_sprite.h"

// Declaración adelantada
class Texture;

// Estructura de Animación
struct Animation
{
    std::string name;              // Nombre de la animación
    std::vector<SDL_FRect> frames; // Frames que componen la animación
    int speed;                     // Velocidad de reproducción
    int loop;                      // Frame de vuelta al terminar (-1 para no repetir)
    bool completed;                // Indica si la animación ha finalizado
    int current_frame;             // Frame actual en reproducción
    int counter;                   // Contador para la animación

    Animation() : name(std::string()), speed(5), loop(0), completed(false), current_frame(0), counter(0) {}
};

// Alias de tipo para buffer de animaciones
using AnimationsFileBuffer = std::vector<std::string>;

// Carga las animaciones desde un fichero en un vector de strings
AnimationsFileBuffer loadAnimationsFromFile(const std::string &file_path);

// Clase AnimatedSprite: Sprite animado que hereda de MovingSprite
class AnimatedSprite : public MovingSprite
{
public:
    // --- Constructores y destructor ---
    AnimatedSprite(std::shared_ptr<Texture> texture, const std::string &file_path);
    AnimatedSprite(std::shared_ptr<Texture> texture, const AnimationsFileBuffer &animations);
    explicit AnimatedSprite(std::shared_ptr<Texture> texture) : MovingSprite(texture) {}
    virtual ~AnimatedSprite() override = default;

    // --- Métodos principales ---
    void update() override; // Actualiza la animación

    // --- Control de animaciones ---
    void setCurrentAnimation(const std::string &name = "default"); // Establece la animación por nombre
    void setCurrentAnimation(int index = 0);                       // Establece la animación por índice
    void resetAnimation();                                         // Reinicia la animación actual

    // --- Consultas ---
    bool animationIsCompleted();           // Comprueba si la animación ha terminado
    int getIndex(const std::string &name); // Obtiene el índice de una animación por nombre

protected:
    // --- Datos de animación ---
    std::vector<Animation> animations_; // Vector de animaciones disponibles
    int current_animation_ = 0;         // Índice de la animación activa

    // --- Métodos internos ---
    void animate();                                                        // Calcula el frame actual de la animación
    void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source); // Carga animaciones desde un buffer
};