#pragma once

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

#include "core/rendering/sprite/animated_sprite.hpp"  // Para AnimatedSprite

class Texture;

// --- Clase SmartSprite: sprite animado que se mueve hacia un destino y puede deshabilitarse automáticamente ---
class SmartSprite : public AnimatedSprite {
   public:
    // --- Constructor y destructor ---
    explicit SmartSprite(std::shared_ptr<Texture> texture)
        : AnimatedSprite(std::move(texture)) {}
    ~SmartSprite() override = default;

    // --- Métodos principales ---
    void update(float delta_time) override;  // Actualiza la posición y comprueba si ha llegado a su destino (time-based)
    void render() override;                  // Dibuja el sprite

    // --- Getters ---
    [[nodiscard]] auto getDestX() const -> int { return dest_x_; }                  // Obtiene la posición de destino en X
    [[nodiscard]] auto getDestY() const -> int { return dest_y_; }                  // Obtiene la posición de destino en Y
    [[nodiscard]] auto isOnDestination() const -> bool { return on_destination_; }  // Indica si está en el destino
    [[nodiscard]] auto hasFinished() const -> bool { return finished_; }            // Indica si ya ha terminado

    // --- Setters ---
    void setFinishedDelay(float value) { finished_delay_ms_ = value; }  // Establece el retraso para deshabilitarlo (ms)
    void setDestX(int x) { dest_x_ = x; }                               // Establece la posición de destino en X
    void setDestY(int y) { dest_y_ = y; }                               // Establece la posición de destino en Y
    void setEnabled(bool value) { enabled_ = value; }                   // Habilita o deshabilita el objeto

   private:
    // --- Variables de estado ---
    int dest_x_ = 0;                  // Posición de destino en el eje X
    int dest_y_ = 0;                  // Posición de destino en el eje Y
    float finished_delay_ms_ = 0.0F;  // Retraso para deshabilitarlo (ms)
    float finished_timer_ = 0.0F;     // Timer acumulado (ms)
    bool on_destination_ = false;     // Indica si está en el destino
    bool finished_ = false;           // Indica si ya ha terminado
    bool enabled_ = false;            // Indica si el objeto está habilitado

    // --- Métodos internos ---
    void checkFinished(float delta_time);  // Comprueba si ha terminado (time-based)
    void checkMove();                      // Comprueba el movimiento
};