#include "core/input/global_inputs.hpp"

#include <cstdio>
#include <string>

#include "core/input/key_config.hpp"
#include "core/jail/jinput.hpp"
#include "core/locale/locale.hpp"
#include "core/rendering/overlay.hpp"
#include "core/rendering/screen.hpp"
#include "game/options.hpp"

namespace GlobalInputs {

    static bool dec_zoom_prev = false;
    static bool inc_zoom_prev = false;
    static bool fullscreen_prev = false;
    static bool shader_prev = false;
    static bool aspect_prev = false;
    static bool ss_prev = false;
    static bool next_shader_prev = false;
    static bool next_preset_prev = false;
    static bool texture_filter_prev = false;
    static bool render_info_prev = false;

    auto handle() -> bool {
        bool consumed = false;

        // F1 — Reduir zoom
        bool dec_zoom = Ji::keyPressed(KeyConfig::scancode("dec_zoom"));
        if (dec_zoom && !dec_zoom_prev) {
            Screen::get()->decZoom();
            char msg[32];
            snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom());
            Overlay::showNotification(msg);
        }
        if (dec_zoom) {
            consumed = true;
        }
        dec_zoom_prev = dec_zoom;

        // F2 — Augmentar zoom
        bool inc_zoom = Ji::keyPressed(KeyConfig::scancode("inc_zoom"));
        if (inc_zoom && !inc_zoom_prev) {
            Screen::get()->incZoom();
            char msg[32];
            snprintf(msg, sizeof(msg), Locale::get("notifications.zoom_fmt"), Screen::get()->getZoom());
            Overlay::showNotification(msg);
        }
        if (inc_zoom) {
            consumed = true;
        }
        inc_zoom_prev = inc_zoom;

        // F3 — Toggle pantalla completa
        bool fullscreen = Ji::keyPressed(KeyConfig::scancode("fullscreen"));
        if (fullscreen && !fullscreen_prev) {
            Screen::get()->toggleFullscreen();
            Overlay::showNotification(Screen::get()->isFullscreen() ? Locale::get("notifications.fullscreen") : Locale::get("notifications.windowed"));
        }
        if (fullscreen) {
            consumed = true;
        }
        fullscreen_prev = fullscreen;

        // F4 — Toggle shaders
        bool shader = Ji::keyPressed(KeyConfig::scancode("toggle_shader"));
        if (shader && !shader_prev) {
            Screen::get()->toggleShaders();
            Overlay::showNotification(Options::video.shader_enabled ? Locale::get("notifications.shader_on") : Locale::get("notifications.shader_off"));
        }
        if (shader) {
            consumed = true;
        }
        shader_prev = shader;

        // F5 — Toggle aspect ratio 4:3
        bool aspect = Ji::keyPressed(KeyConfig::scancode("toggle_aspect_ratio"));
        if (aspect && !aspect_prev) {
            Screen::get()->toggleAspectRatio();
            Overlay::showNotification(Options::video.aspect_ratio_4_3 ? Locale::get("notifications.aspect_43") : Locale::get("notifications.aspect_square"));
        }
        if (aspect) {
            consumed = true;
        }
        aspect_prev = aspect;

        // F6 — Toggle supersampling
        bool ss = Ji::keyPressed(KeyConfig::scancode("toggle_supersampling"));
        if (ss && !ss_prev) {
            if (Screen::get()->toggleSupersampling()) {
                Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off"));
            }
        }
        if (ss) {
            consumed = true;
        }
        ss_prev = ss;

        // F7 — Canviar tipus de shader (PostFX ↔ CrtPi)
        bool next_shader = Ji::keyPressed(KeyConfig::scancode("next_shader"));
        if (next_shader && !next_shader_prev) {
            if (Screen::get()->nextShaderType()) {
                char msg[64];
                snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName());
                Overlay::showNotification(msg);
            }
        }
        if (next_shader) {
            consumed = true;
        }
        next_shader_prev = next_shader;

        // F8 — Pròxim preset del shader actiu
        bool next_preset = Ji::keyPressed(KeyConfig::scancode("next_shader_preset"));
        if (next_preset && !next_preset_prev) {
            if (Screen::get()->nextPreset()) {
                char msg[64];
                snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName());
                Overlay::showNotification(msg);
            }
        }
        if (next_preset) {
            consumed = true;
        }
        next_preset_prev = next_preset;

        // F9 — Cicla filtre de textura (NEAREST ↔ LINEAR), sempre aplicat
        bool texture_filter = Ji::keyPressed(KeyConfig::scancode("cycle_texture_filter"));
        if (texture_filter && !texture_filter_prev) {
            Screen::get()->cycleTextureFilter(+1);
            Overlay::showNotification(Options::video.texture_filter == Options::TextureFilter::LINEAR
                    ? Locale::get("notifications.filter_linear")
                    : Locale::get("notifications.filter_nearest"));
        }
        if (texture_filter) {
            consumed = true;
        }
        texture_filter_prev = texture_filter;

        // F10 — Toggle render info (FPS, driver, shader)
        bool render_info = Ji::keyPressed(KeyConfig::scancode("toggle_render_info"));
        if (render_info && !render_info_prev) {
            Overlay::toggleRenderInfo();
        }
        if (render_info) {
            consumed = true;
        }
        render_info_prev = render_info;

        return consumed;
    }

}  // namespace GlobalInputs
