#pragma once

#include <SDL3/SDL_rect.h>	 // Para SDL_FRect
#include <SDL3/SDL_render.h> // Para SDL_Renderer
#include <memory>			 // Para shared_ptr
#include <string>			 // Para string
#include <vector>			 // Para vector
#include "utils.h"			 // Para Color

class Sprite;
class Text;
class Texture;

// --- Clase Notifier: gestiona las notificaciones en pantalla (singleton) ---
class Notifier
{
public:
	// [SINGLETON] Crearemos el objeto con esta función estática
	static void init(const std::string &icon_file, std::shared_ptr<Text> text);

	// [SINGLETON] Destruiremos el objeto con esta función estática
	static void destroy();

	// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
	static Notifier *get();

	// Dibuja las notificaciones por pantalla
	void render();

	// Actualiza el estado de las notificaciones
	void update();

	// Muestra una notificación de texto por pantalla
	void show(std::vector<std::string> texts, int icon = -1, const std::string &code = std::string());

	// Indica si hay notificaciones activas
	bool isActive() const { return !notifications_.empty(); }

	// Obtiene los códigos de las notificaciones activas
	std::vector<std::string> getCodes();

	// Comprueba si hay alguna notificación con un código concreto
	bool checkCode(const std::string &code) { return stringInVector(getCodes(), code); }

private:
	// [SINGLETON] Objeto notifier
	static Notifier *notifier_;

	// --- Tipos internos ---
	enum class NotificationStatus
	{
		RISING,
		STAY,
		VANISHING,
		FINISHED,
	};

	enum class NotificationShape
	{
		ROUNDED,
		SQUARED,
	};

	// --- Estructura Notification ---
	struct Notification
	{
		std::shared_ptr<Texture> texture; // Textura de la notificación
		std::shared_ptr<Sprite> sprite;	  // Sprite asociado
		std::vector<std::string> texts;	  // Textos a mostrar
		int counter;					  // Contador de tiempo
		NotificationStatus state;		  // Estado de la notificación
		NotificationShape shape;		  // Forma de la notificación
		SDL_FRect rect;					  // Rectángulo de la notificación
		int y;							  // Posición vertical
		int travel_dist;				  // Distancia a recorrer
		std::string code;				  // Código identificador de la notificación

		// Constructor
		explicit Notification()
			: texture(nullptr), sprite(nullptr), texts(), counter(0), state(NotificationStatus::RISING),
			  shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {}
	};

	// --- Objetos y punteros ---
	SDL_Renderer *renderer_;				// El renderizador de la ventana
	std::shared_ptr<Texture> icon_texture_; // Textura para los iconos de las notificaciones
	std::shared_ptr<Text> text_;			// Objeto para dibujar texto

	// --- Variables de estado ---
	Color bg_color_;						  // Color de fondo de las notificaciones
	int wait_time_;							  // Tiempo que se ve la notificación
	std::vector<Notification> notifications_; // Lista de notificaciones activas
	bool stack_;							  // Indica si las notificaciones se apilan
	bool has_icons_;						  // Indica si el notificador tiene textura para iconos

	// --- Métodos internos ---
	void clearFinishedNotifications(); // Elimina las notificaciones finalizadas
	void clearAllNotifications();	   // Finaliza y elimina todas las notificaciones activas

	// [SINGLETON] Constructor y destructor privados
	Notifier(std::string icon_file, std::shared_ptr<Text> text);
	~Notifier() = default;
};
