#pragma once

#include <SDL3/SDL.h>  // Para SDL_AppResult, SDL_Event

#include <memory>  // Para unique_ptr
#include <string>  // Para string

#include "core/system/section.hpp"  // Para Section::Name

namespace Lang {
    enum class Code : int;
}

// Declaraciones adelantadas de las secciones
class Preload;
class Logo;
class Intro;
class Title;
class Game;
class Instructions;
class HiScoreTable;
class Credits;

// --- Clase Director: gestor principal de la aplicación ---
class Director {
   public:
    // --- Constructor y destructor ---
    Director();
    ~Director();

    // --- Callbacks para SDL_MAIN_USE_CALLBACKS ---
    auto iterate() -> SDL_AppResult;                      // Avanza un frame de la sección activa
    auto handleEvent(SDL_Event& event) -> SDL_AppResult;  // Procesa un evento SDL

    // --- Debug config (accesible desde otras clases) ---
    struct DebugConfig {
        std::string initial_section;
        std::string initial_options;
        int initial_stage = 0;
        bool show_render_info = true;
        std::string resource_loading;
        bool autoplay = false;
        bool invincibility = false;

        DebugConfig()
            : initial_section("game"),
              initial_options("1p"),
              resource_loading("preload") {}
    };
    static inline DebugConfig debug_config;

   private:
    // --- Variables internas ---
    std::string executable_path_;  // Ruta del ejecutable
    std::string system_folder_;    // Carpeta del sistema para almacenar datos

    // --- Sección activa (una y sólo una viva en cada momento) ---
    std::unique_ptr<Preload> preload_;
    std::unique_ptr<Logo> logo_;
    std::unique_ptr<Intro> intro_;
    std::unique_ptr<Title> title_;
    std::unique_ptr<Game> game_;
    std::unique_ptr<Instructions> instructions_;
    std::unique_ptr<HiScoreTable> hi_score_table_;
    std::unique_ptr<Credits> credits_;
    Section::Name last_built_section_name_ = Section::Name::RESET;

    // --- Fase de arranque no bloqueante ---
    bool boot_loading_ = true;  // True mientras Resource::loadStep está cargando incremental

    // --- Inicialización y cierre del sistema ---
    void init();          // Inicializa la aplicación (pre-boot)
    void finishBoot();    // Post-boot: inicializa lo que depende de recursos cargados
    static void close();  // Cierra y libera recursos

    // --- Configuración inicial ---
    static void loadParams();                            // Carga los parámetros del programa
    static void loadScoreFile();                         // Carga el fichero de puntuaciones
    void createSystemFolder(const std::string& folder);  // Crea la carpeta del sistema
    void loadDebugConfig();                              // Carga debug.yaml (solo en _DEBUG)

    // --- Gestión de entrada y archivos ---
    void loadAssets();  // Crea el índice de archivos disponibles

    // --- Gestión de secciones ---
    void handleSectionTransition();  // Destruye la sección anterior y construye la nueva si Section::name ha cambiado
    void resetActiveSection();       // Libera todos los unique_ptr de sección
    static void reset();             // Reinicia objetos y vuelve a la sección inicial

    // --- Gestión de archivos de idioma ---
    auto getLangFile(Lang::Code code) -> std::string;  // Obtiene un fichero de idioma según el código

    // --- Apagado del sistema ---
    static void shutdownSystem(bool should_shutdown);  // Apaga el sistema
};
