#pragma once

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

#include "moving_sprite.h"

// Declaraciones adelantadas
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 Tipos ===
using AnimationsFileBuffer = std::vector<std::string>;

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

class AnimatedSprite : public MovingSprite
{
public:
    // Constructores
    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;

    // === Actualización ===
    void update() override; // Actualiza la animación

    // === Control de Animaciones ===
    void setCurrentAnimation(const std::string &name = "default"); // Establecer por nombre
    void setCurrentAnimation(int index = 0);                       // Establecer por índice
    void resetAnimation();                                         // Reiniciar la animación

    // === Consultas ===
    bool animationIsCompleted();           // Comprobar si ha terminado
    int getIndex(const std::string &name); // Obtener índice 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();                                                        // Calcular el frame actual de la animación
    void loadFromAnimationsFileBuffer(const AnimationsFileBuffer &source); // Cargar desde buffer
};