#pragma once

#include <string>
#include <vector>

#include "utils.h"

// === Enumeraciones ===
enum class AssetType : int
{
	BITMAP,
	MUSIC,
	SOUND,
	FONT,
	LANG,
	DATA,
	ANIMATION,
	PALETTE,
	ITEM,
	MAX_ASSET_TYPE,
};

class Asset
{
public:
	// === Singleton ===
	static Asset &get() // Obtención de la instancia única (Meyers Singleton)
	{
		static Asset instance;
		return instance;
	}

	// === Inicialización ===
	void init(const std::string &executable_path)
	{
		executable_path_ = getPath(executable_path);
	}

	// === Gestión de Recursos ===
	void add(const std::string &file, AssetType type, bool required = true, bool absolute = false); // Añadir recurso
	std::string get(const std::string &text) const;													// Obtener ruta completa
	bool check() const;																				// Verificar existencia
	std::vector<std::string> getListByType(AssetType type) const;									// Lista por tipo

private:
	// === Estructura Interna ===
	struct AssetItem
	{
		std::string file; // Ruta del fichero desde la raíz del directorio
		AssetType type;	  // Tipo de recurso
		bool required;	  // Indica si el fichero es obligatorio

		AssetItem(const std::string &filePath, AssetType assetType, bool isRequired)
			: file(filePath), type(assetType), required(isRequired) {}
	};

	// === Variables Internas ===
	int longest_name_ = 0;			   // Longitud del nombre más largo
	std::vector<AssetItem> file_list_; // Lista con todas las rutas
	std::string executable_path_;	   // Ruta del ejecutable

	// === Métodos Internos ===
	bool checkFile(const std::string &path) const; // Verificar si archivo existe
	std::string getTypeName(AssetType type) const; // Obtener nombre textual del tipo

	// === Patrón Singleton ===
	Asset() = default;						  // Constructor privado
	~Asset() = default;						  // Destructor privado
	Asset(const Asset &) = delete;			  // Evitar copia
	Asset &operator=(const Asset &) = delete; // Evitar asignación
};