#pragma once

#include <cstdint>
#include <string>
#include <vector>

#include "game/defaults.hpp"
#include "game/defines.hpp"

namespace Options {

    // Tecles de joc (moviment, accions). Les tecles d'UI viuen ara a KeyConfig
    // (carregades de data/input/keys.yaml).
    struct KeysGame {
        SDL_Scancode up{Defaults::KeysGame::UP};
        SDL_Scancode down{Defaults::KeysGame::DOWN};
        SDL_Scancode left{Defaults::KeysGame::LEFT};
        SDL_Scancode right{Defaults::KeysGame::RIGHT};
        SDL_Scancode exit{Defaults::KeysGame::EXIT};
    };

    // Posició del render info
    enum class RenderInfoPosition : std::uint8_t { OFF = 0,
        TOP = 1,
        BOTTOM = 2 };

    // Filtre de textura per a l'upscale final (sempre, no només en 4:3)
    enum class TextureFilter : std::uint8_t { NEAREST = 0,
        LINEAR = 1 };

    // Mode de presentació lògica (escala finestra): mapeja directament
    // als valors de SDL_RendererLogicalPresentation.
    enum class ScalingMode : std::uint8_t { DISABLED = 0,
        STRETCH = 1,
        LETTERBOX = 2,
        OVERSCAN = 3,
        INTEGER = 4 };

    // Opcions de vídeo
    struct Video {
        bool gpu_acceleration{Defaults::Video::GPU_ACCELERATION};
        bool shader_enabled{Defaults::Video::SHADER_ENABLED};
        bool supersampling{Defaults::Video::SUPERSAMPLING};
        ScalingMode scaling_mode{ScalingMode::INTEGER};
        bool vsync{Defaults::Video::VSYNC};
        bool aspect_ratio_4_3{Defaults::Video::ASPECT_RATIO_4_3};
        TextureFilter texture_filter{TextureFilter::NEAREST};
        int downscale_algo{Defaults::Video::DOWNSCALE_ALGO};
        int internal_resolution{Defaults::Video::INTERNAL_RESOLUTION};  // Multiplicador enter ≥ 1, clampat a max_zoom
        std::string current_shader{"postfx"};                           // "postfx" o "crtpi"
        std::string current_postfx_preset{"CRT"};                       // Nom del preset PostFX actiu
        std::string current_crtpi_preset{"DEFAULT"};                    // Nom del preset CrtPi actiu
    };

    // Opcions del render info
    struct RenderInfo {
        RenderInfoPosition position{RenderInfoPosition::OFF};
        bool show_time{true};
        Uint32 text_color{0xFF00D7FF};    // Groc daurat (ABGR)
        Uint32 shadow_color{0xFF005A6B};  // Ombra daurada fosca (ABGR)
    };

    // Opcions d'àudio (estructura compartida amb la resta de projectes)
    struct Music {
        bool enabled{Defaults::Audio::MUSIC_ENABLED};
        float volume{Defaults::Audio::MUSIC_VOLUME};
    };
    struct Sound {
        bool enabled{Defaults::Audio::SOUND_ENABLED};
        float volume{Defaults::Audio::SOUND_VOLUME};
    };
    struct Audio {
        Music music{};
        Sound sound{};
        bool enabled{Defaults::Audio::ENABLED};  // master enable
        float volume{Defaults::Audio::VOLUME};
    };

    // Opcions de finestra
    struct Window {
        int zoom{Defaults::Window::ZOOM};
        bool fullscreen{Defaults::Window::FULLSCREEN};
    };

    // Opcions de joc
    struct Game {
        int habitacio_inicial{Defaults::Game::HABITACIO_INICIAL};
        int piramide_inicial{Defaults::Game::PIRAMIDE_INICIAL};
        int vides{Defaults::Game::VIDES};
        int diamants_inicial{Defaults::Game::DIAMANTS_INICIAL};
        int diners_inicial{Defaults::Game::DINERS_INICIAL};
        bool use_new_logo{Defaults::Game::USE_NEW_LOGO};
        bool show_title_credits{Defaults::Game::SHOW_TITLE_CREDITS};
        bool show_preload{Defaults::Game::SHOW_PRELOAD};
    };

    // Preset PostFX
    struct PostFXPreset {
        std::string name;
        float vignette{0.6F};
        float scanlines{0.7F};
        float chroma{0.15F};
        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 globals ---
    inline std::string version{};
    inline KeysGame keys_game{};
    inline Video video{};
    inline RenderInfo render_info{};
    inline Audio audio{};
    inline Window window{};
    inline Game game{};
    inline std::string config_file_path{};

    // Presets de shaders
    inline std::vector<PostFXPreset> postfx_presets{};
    inline std::string postfx_file_path{};
    inline int current_postfx_preset{0};

    inline std::vector<CrtPiPreset> crtpi_presets{};
    inline std::string crtpi_file_path{};
    inline int current_crtpi_preset{0};

    inline std::string debug_file_path{};

    // --- API ---
    void setConfigFile(const std::string& path);
    auto loadFromFile() -> bool;
    auto saveToFile() -> bool;

    // debug.yaml: estat inicial de gameplay per a tests ràpids
    // (`habitacio_inicial`, `piramide_inicial`, `vides`, `diamants_inicial`,
    // `diners_inicial`). Només es carrega/desa en builds de debug; en release
    // els camps queden als seus defaults.
    void setDebugFile(const std::string& path);
    auto loadDebugFromFile() -> bool;
    auto saveDebugToFile() -> bool;

    void setPostFXFile(const std::string& path);
    auto loadPostFXFromFile() -> bool;

    void setCrtPiFile(const std::string& path);
    auto loadCrtPiFromFile() -> bool;

    // Sincronitza Options::audio → jail_audio (aplica volums i enables).
    // Volum efectiu = master * volum_individual per a música i sons.
    void applyAudio();

}  // namespace Options
