#pragma once

#include <cstdint>  // for uint8_t
#include <string>   // for string, basic_string
#include <vector>   // for vector

// Clase Asset
class Asset {
   public:
    // Tipos de recurso
    enum class Type : std::uint8_t {
        BITMAP,
        MUSIC,
        SOUND,
        FONT,
        LANG,
        DATA,
        ROOM,
        ENEMY,
        ITEM,
        COUNT  // Centinela: número total de tipos
    };

    // Estructura para definir un item
    struct Item {
        std::string file;  // Ruta del fichero desde la raiz del directorio
        Type type;         // Indica el tipo de recurso
        bool required;     // Indica si es un fichero que debe de existir
    };

    // Singleton API
    static void init(const std::string &executable_path);  // Crea la instancia
    static void destroy();                                 // Libera la instancia
    static auto get() -> Asset *;                          // Obtiene el puntero a la instancia

    void add(const std::string &file, Type type, bool required = true, bool absolute = false);  // Añade un elemento a la lista
    auto get(const std::string &text) -> std::string;                                           // Devuelve un elemento de la lista a partir de una cadena
    [[nodiscard]] auto getAll() const -> const std::vector<Item> & { return file_list_; }       // Devuelve toda la lista de items registrados
    auto check() -> bool;                                                                       // Comprueba que existen todos los elementos
    void setVerbose(bool value);                                                                // Establece si ha de mostrar texto por pantalla

   private:
    // Variables
    int longest_name_{0};          // Contiene la longitud del nombre de fichero mas largo
    std::vector<Item> file_list_;  // Listado con todas las rutas a los ficheros
    std::string executable_path_;  // Ruta al ejecutable
    bool verbose_{true};           // Indica si ha de mostrar información por pantalla

    static Asset *instance;  // Instancia única

    explicit Asset(const std::string &path);  // Constructor privado (usar Asset::init)

    [[nodiscard]] auto checkFile(const std::string &executable_path) const -> bool;  // Comprueba que existe un fichero
    static auto getTypeName(Type type) -> std::string;                               // Devuelve el nombre del tipo de recurso
};
