#pragma once

#ifdef _DEBUG

#include <SDL3/SDL.h>

#include <map>     // Para map
#include <string>  // Para string
#include <vector>  // Para vector

#include "game/scene_manager.hpp"  // Para SceneManager::Scene

// Clase Debug
class Debug {
   public:
    struct SpawnSettings {
        std::string room;
        int spawn_x = 0;
        int spawn_y = 0;
        SDL_FlipMode flip = SDL_FLIP_NONE;
    };

    static void init();           // [SINGLETON] Crearemos el objeto con esta función estática
    static void destroy();        // [SINGLETON] Destruiremos el objeto con esta función estática
    static auto get() -> Debug*;  // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él

    void render();  // Dibuja en pantalla

    void setPos(SDL_FPoint p);  // Establece la posición donde se colocará la información de debug

    [[nodiscard]] auto isEnabled() const -> bool { return enabled_; }  // Obtiene si el debug está activo

    void add(const std::string& text) { slot_.push_back(text); }      // Añade texto one-shot al slot (se limpia cada frame)
    void clear() { slot_.clear(); }                                   // Limpia el slot one-shot (no afecta a watches)
    void addToLog(const std::string& text) { log_.push_back(text); }  // Añade texto al log
    void clearLog() { log_.clear(); }                                 // Limpia el log
    void set(const std::string& key, const std::string& value);       // Establece/actualiza un valor persistente en el watch window
    void unset(const std::string& key);                               // Elimina un valor del watch window
    void clearWatches() { watches_.clear(); }                         // Limpia todos los watches
    void setEnabled(bool value) { enabled_ = value; }                 // Establece si el debug está activo
    void toggleEnabled() { enabled_ = !enabled_; }                    // Alterna el estado del debug

    void setDebugFile(const std::string& path);                                                      // Establece la ruta del archivo debug.yaml
    void loadFromFile();                                                                             // Carga la configuración de debug desde debug.yaml
    void saveToFile() const;                                                                         // Guarda la configuración de debug en debug.yaml
    [[nodiscard]] auto getSpawnSettings() const -> const SpawnSettings& { return spawn_settings_; }  // Obtiene los valores de spawn
    void setSpawnSettings(const SpawnSettings& s) { spawn_settings_ = s; }                           // Establece los valores de spawn
    [[nodiscard]] auto getInitialScene() const -> SceneManager::Scene { return initial_scene_; }     // Obtiene la escena inicial de debug
    void setInitialScene(SceneManager::Scene s) { initial_scene_ = s; }                              // Establece la escena inicial de debug
    [[nodiscard]] auto getLazyLoading() const -> bool { return lazy_loading_; }                      // Indica si el modo lazy de recursos está activo
    [[nodiscard]] auto getRenderInfoEnabled() const -> bool { return render_info_enabled_; }         // Indica si el overlay RenderInfo arranca activo
    void setRenderInfoEnabled(bool value);                                                           // Persiste el estado del overlay RenderInfo en debug.yaml

   private:
    static Debug* debug;  // [SINGLETON] Objeto privado

    Debug() = default;   // Constructor
    ~Debug() = default;  // Destructor

    // Variables
    std::map<std::string, std::string> watches_;                     // Watch window: valores persistentes (key→value)
    std::vector<std::string> slot_;                                  // One-shot: textos que se limpian cada frame
    std::vector<std::string> log_;                                   // Log persistente
    int x_ = 0;                                                      // Posicion donde escribir el texto de debug
    int y_ = 0;                                                      // Posición donde escribir el texto de debug
    bool enabled_ = false;                                           // Indica si esta activo el modo debug
    std::string debug_file_path_;                                    // Ruta del archivo debug.yaml
    SpawnSettings spawn_settings_;                                   // Configuración de spawn para debug
    SceneManager::Scene initial_scene_ = SceneManager::Scene::GAME;  // Escena inicial en debug
    bool lazy_loading_ = false;                                      // Carga lazy de recursos (dev)
    bool render_info_enabled_ = false;                               // Overlay de RenderInfo activo al arrancar
};

#endif  // _DEBUG