#pragma once

#include <SDL3/SDL.h>

#include <memory>  // Para shared_ptr
#include <string>  // Para string
#include <utility>
#include <vector>  // Para vector

#include "core/rendering/surface_moving_sprite.hpp"  // Para SMovingSprite
class Surface;                                       // lines 9-9

struct AnimationData {
        std::string name;               // Nombre de la animacion
        std::vector<SDL_FRect> frames;  // Cada uno de los frames que componen la animación
        float speed{0.083F};            // Velocidad de la animación (segundos por frame)
        int loop{0};                    // Indica a que frame vuelve la animación al terminar. -1 para que no vuelva
        bool completed{false};          // Indica si ha finalizado la animación
        int current_frame{0};           // Frame actual
        float accumulated_time{0.0F};   // Tiempo acumulado para las animaciones (time-based)

        // DEPRECATED: Mantener compatibilidad con sistema antiguo
        int counter{0};                 // Contador para las animaciones (frame-based, deprecated)

        AnimationData()

            = default;
};

using Animations = std::vector<std::string>;

// Carga las animaciones en un vector(Animations) desde un fichero
auto loadAnimationsFromFile(const std::string& file_path) -> Animations;

class SurfaceAnimatedSprite : public SurfaceMovingSprite {
    protected:
        // Variables
        std::vector<AnimationData> animations_;  // Vector con las diferentes animaciones
        int current_animation_ = 0;              // Animacion activa

        // Calcula el frame correspondiente a la animación actual (time-based)
        void animate(float delta_time);

        // Calcula el frame correspondiente a la animación actual (frame-based, deprecated)
        void animate();

        // Carga la animación desde un vector de cadenas
        void setAnimations(const Animations& animations);

    public:
        // Constructor
        SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const std::string& file_path);
        SurfaceAnimatedSprite(std::shared_ptr<Surface> surface, const Animations& animations);
        explicit SurfaceAnimatedSprite(std::shared_ptr<Surface> surface)
            : SurfaceMovingSprite(std::move(surface)) {}

        // Destructor
        ~SurfaceAnimatedSprite() override = default;

        // Actualiza las variables del objeto (time-based)
        void update(float delta_time) override;

        // Actualiza las variables del objeto (frame-based, deprecated)
        [[deprecated("Use update(float delta_time) instead")]]
        void update() override;

        // Comprueba si ha terminado la animación
        auto animationIsCompleted() -> bool;

        // Obtiene el indice de la animación a partir del nombre
        auto getIndex(const std::string& name) -> int;

        // Establece la animacion actual
        void setCurrentAnimation(const std::string& name = "default");
        void setCurrentAnimation(int index = 0);

        // Reinicia la animación
        void resetAnimation();

        // Establece el frame actual de la animación
        void setCurrentAnimationFrame(int num);

        // Obtiene el numero de frames de la animación actual
        auto getCurrentAnimationSize() -> int { return static_cast<int>(animations_[current_animation_].frames.size()); }
};