#pragma once

#include <SDL3/SDL_rect.h> // Para SDL_FPoint
#include <functional>	   // Para std::function
#include <memory>		   // Para shared_ptr
#include <vector>		   // Para vector
#include "sprite.h"		   // Para Sprite

class Texture;

// --- Tipos de recorrido ---
enum class PathType
{
	VERTICAL,
	HORIZONTAL,
};

// --- Centrado del recorrido ---
enum class PathCentered
{
	ON_X,
	ON_Y,
	NONE,
};

// --- Estructura Path: define un recorrido para el sprite ---
struct Path
{
	std::vector<SDL_FPoint> spots; // Puntos por los que se desplazará el sprite
	int waiting_counter;		   // Tiempo de espera una vez en el destino
	bool on_destination = false;   // Indica si ha llegado al destino
	bool finished = false;		   // Indica si ha terminado de esperarse
	int counter = 0;			   // Contador interno

	// Constructor
	Path(const std::vector<SDL_FPoint> &spots_init, int waiting_counter_init)
		: spots(spots_init), waiting_counter(waiting_counter_init) {}
};

// Devuelve un vector con los puntos que conforman la ruta
std::vector<SDL_FPoint> createPath(float start, float end, PathType type, float fixed_pos, int steps, const std::function<double(double)> &easingFunction);

// --- Clase PathSprite: Sprite que sigue uno o varios recorridos ---
class PathSprite : public Sprite
{
public:
	// --- Constructor y destructor ---
	explicit PathSprite(std::shared_ptr<Texture> texture)
		: Sprite(texture) {}
	~PathSprite() override = default;

	// --- Métodos principales ---
	void update();			// Actualiza la posición del sprite según el recorrido
	void render() override; // Muestra el sprite por pantalla

	// --- Gestión de recorridos ---
	void addPath(Path path, bool centered = false);																											 // Añade un recorrido (Path)
	void addPath(std::vector<SDL_FPoint> spots, int waiting_counter = 0);																					 // Añade un recorrido a partir de puntos
	void addPath(int start, int end, PathType type, int fixed_pos, int steps, const std::function<double(double)> &easingFunction, int waiting_counter = 0); // Añade un recorrido generado

	// --- Estado y control ---
	void enable();		// Habilita el objeto
	bool hasFinished(); // Indica si ha terminado todos los recorridos

	// --- Getters ---
	int getCurrentPath() const { return current_path_; } // Devuelve el índice del recorrido actual

private:
	// --- Variables internas ---
	bool enabled_ = false;		// Indica si el objeto está habilitado
	bool has_finished_ = false; // Indica si el objeto ha finalizado el recorrido
	int current_path_ = 0;		// Recorrido que se está recorriendo actualmente
	std::vector<Path> paths_;	// Caminos a recorrer por el sprite

	// --- Métodos internos ---
	void moveThroughCurrentPath(); // Coloca el sprite en los diferentes puntos del recorrido
	void goToNextPathOrDie();	   // Cambia de recorrido o finaliza
};