#pragma once

#include <SDL3/SDL.h>

#include <string>
#include <vector>

#include "core/rendering/shader_backend.hpp"  // for Rendering::ShaderType
#include "game/defaults.hpp"
#include "utils/utils.h"  // for input_t, palette_e

// =============================================================================
// Opciones del programa, alineades amb coffee_crisis_arcade_edition.
// L'estat viu en globals dins el namespace Options:: (window, video, audio,
// loading, settings, inputs). La persistència usa fkyaml i es guarda a
// config.yaml dins la carpeta de configuració del sistema.
// =============================================================================

namespace Options {

    struct Window {
        std::string caption = Defaults::Window::CAPTION;
        int zoom = Defaults::Window::ZOOM;
        int max_zoom = Defaults::Window::MAX_ZOOM;
    };

    struct GPU {
        bool acceleration = Defaults::Video::GPU_ACCELERATION;
        std::string preferred_driver = Defaults::Video::GPU_PREFERRED_DRIVER;
    };

    struct Supersampling {
        bool enabled = Defaults::Video::SUPERSAMPLING;
        bool linear_upscale = Defaults::Video::LINEAR_UPSCALE;
        int downscale_algo = Defaults::Video::DOWNSCALE_ALGO;
    };

    struct ShaderConfig {
        bool enabled = Defaults::Video::SHADER_ENABLED;
        Rendering::ShaderType current_shader = Rendering::ShaderType::POSTFX;
        std::string current_postfx_preset_name = "CRT";
        std::string current_crtpi_preset_name = "Default";
        int current_postfx_preset = 0;
        int current_crtpi_preset = 0;
    };

    struct Video {
        SDL_ScaleMode scale_mode = Defaults::Video::SCALE_MODE;
        bool fullscreen = Defaults::Video::FULLSCREEN;
        bool vsync = Defaults::Video::VSYNC;
        bool integer_scale = Defaults::Video::INTEGER_SCALE;
        GPU gpu;
        Supersampling supersampling;
        ShaderConfig shader;
    };

    struct Music {
        bool enabled = Defaults::Music::ENABLED;
        float volume = Defaults::Music::VOLUME;
    };

    struct Sound {
        bool enabled = Defaults::Sound::ENABLED;
        float volume = Defaults::Sound::VOLUME;
    };

    struct Audio {
        bool enabled = Defaults::Audio::ENABLED;
        float volume = Defaults::Audio::VOLUME;
        Music music;
        Sound sound;
    };

    struct Loading {
        bool show = Defaults::Loading::SHOW;
        bool show_resource_name = Defaults::Loading::SHOW_RESOURCE_NAME;
        bool wait_for_input = Defaults::Loading::WAIT_FOR_INPUT;
    };

    struct Settings {
        static constexpr int CURRENT_CONFIG_VERSION = 1;
        int config_version = CURRENT_CONFIG_VERSION;
        int difficulty = Defaults::Settings::DIFFICULTY;
        int language = Defaults::Settings::LANGUAGE;
        palette_e palette = Defaults::Settings::PALETTE;
        bool console = false;
        int player_selected = 0;
        std::string config_file;
    };

    // Preset PostFX
    struct PostFXPreset {
        std::string name;
        float vignette{0.0F};
        float scanlines{0.0F};
        float chroma{0.0F};
        float mask{0.0F};
        float gamma{0.0F};
        float curvature{0.0F};
        float bleeding{0.0F};
        float flicker{0.0F};
    };

    // Preset CrtPi
    struct CrtPiPreset {
        std::string name;
        float scanline_weight{6.0F};
        float scanline_gap_brightness{0.12F};
        float bloom_factor{3.5F};
        float input_gamma{2.4F};
        float output_gamma{2.2F};
        float mask_brightness{0.80F};
        float curvature_x{0.05F};
        float curvature_y{0.10F};
        int mask_type{2};
        bool enable_scanlines{true};
        bool enable_multisample{true};
        bool enable_gamma{true};
        bool enable_curvature{false};
        bool enable_sharper{false};
    };

    // --- Variables globales ---
    extern Window window;
    extern Video video;
    extern Audio audio;
    extern Loading loading;
    extern Settings settings;
    extern std::vector<input_t> inputs;  // [0]=KEYBOARD, [1]=GAMECONTROLLER per defecte

    // Presets de shaders (carregats de postfx.yaml / crtpi.yaml al config folder)
    extern std::vector<PostFXPreset> postfx_presets;
    extern std::string postfx_file_path;
    extern int current_postfx_preset;  // Índex dins `postfx_presets`

    extern std::vector<CrtPiPreset> crtpi_presets;
    extern std::string crtpi_file_path;
    extern int current_crtpi_preset;  // Índex dins `crtpi_presets`

    // --- Funciones ---
    void init();                                       // Reinicia a defaults i omple `inputs`
    void setConfigFile(const std::string &file_path);  // Ruta del config.yaml
    auto loadFromFile() -> bool;                       // Carrega el YAML; si no existeix, crea'l amb defaults
    auto saveToFile() -> bool;                         // Guarda el YAML

    // Presets de shaders. Si el fitxer no existeix, l'escriu amb els defaults
    // i deixa els presets carregats en memòria.
    void setPostFXFile(const std::string &path);
    auto loadPostFXFromFile() -> bool;
    void setCrtPiFile(const std::string &path);
    auto loadCrtPiFromFile() -> bool;

}  // namespace Options
