#include "input_handler.hpp"

#include <SDL3/SDL_keycode.h>  // for SDL_Keycode

#include <string>  // for std::string, std::to_string

#include "defines.hpp"         // for KIOSK_NOTIFICATION_TEXT
#include "engine.hpp"          // for Engine
#include "external/mouse.hpp"  // for Mouse namespace

auto InputHandler::processEvents(Engine& engine) -> bool {  // NOLINT(readability-function-cognitive-complexity)
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        // Procesar eventos de ratón (auto-ocultar cursor)
        Mouse::handleEvent(event);

        // Salir del bucle si se detecta una petición de cierre
        if (event.type == SDL_EVENT_QUIT) {
            return true;  // Solicitar salida
        }

        // Procesar eventos de teclado
        if (event.type == SDL_EVENT_KEY_DOWN && static_cast<int>(event.key.repeat) == 0) {
            switch (event.key.key) {
                case SDLK_ESCAPE:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                        break;
                    }
                    return true;  // Solicitar salida

                case SDLK_SPACE:
                    engine.pushBallsAwayFromGravity();
                    break;

                case SDLK_G:
                    engine.handleGravityToggle();
                    break;

                // Controles de dirección de gravedad con teclas de cursor
                case SDLK_UP:
                    engine.handleGravityDirectionChange(GravityDirection::UP, "Gravedad arriba");
                    break;

                case SDLK_DOWN:
                    engine.handleGravityDirectionChange(GravityDirection::DOWN, "Gravedad abajo");
                    break;

                case SDLK_LEFT:
                    engine.handleGravityDirectionChange(GravityDirection::LEFT, "Gravedad izquierda");
                    break;

                case SDLK_RIGHT:
                    engine.handleGravityDirectionChange(GravityDirection::RIGHT, "Gravedad derecha");
                    break;

                case SDLK_V:
                    engine.toggleVSync();
                    break;

                case SDLK_H:
                    engine.toggleHelp();  // Toggle ayuda de teclas
                    break;

                // Toggle Física ↔ Última Figura (antes era C)
                case SDLK_F:
                    engine.toggleShapeMode();
                    break;

                // Selección directa de figuras 3D
                case SDLK_Q:
                    engine.activateShape(ShapeType::SPHERE, "Esfera");
                    break;

                case SDLK_W:
                    engine.activateShape(ShapeType::LISSAJOUS, "Lissajous");
                    break;

                case SDLK_E:
                    engine.activateShape(ShapeType::HELIX, "Hélice");
                    break;

                case SDLK_R:
                    engine.activateShape(ShapeType::TORUS, "Toroide");
                    break;

                case SDLK_T:
                    engine.activateShape(ShapeType::CUBE, "Cubo");
                    break;

                case SDLK_Y:
                    engine.activateShape(ShapeType::CYLINDER, "Cilindro");
                    break;

                case SDLK_U:
                    engine.activateShape(ShapeType::ICOSAHEDRON, "Icosaedro");
                    break;

                case SDLK_I:
                    engine.activateShape(ShapeType::ATOM, "Átomo");
                    break;

                case SDLK_O:
                    // engine.activateShape(ShapeType::PNG_SHAPE, "Forma PNG");
                    break;

                // Toggle Modo Boids (comportamiento de enjambre)
                case SDLK_B:
                    engine.toggleBoidsMode();
                    break;

                // Ciclar temas de color (movido de B a C)
                case SDLK_C: {
                    // Detectar si Shift está presionado
                    SDL_Keymod modstate = SDL_GetModState();
                    if ((modstate & SDL_KMOD_SHIFT) != 0u) {
                        // Shift+C: Ciclar hacia atrás (tema anterior)
                        engine.cycleTheme(false);
                    } else {
                        // C solo: Ciclar hacia adelante (tema siguiente)
                        engine.cycleTheme(true);
                    }
                } break;

                // Temas de colores con teclado numérico (con transición suave)
                case SDLK_KP_1:
                    engine.switchThemeByNumpad(1);
                    break;

                case SDLK_KP_2:
                    engine.switchThemeByNumpad(2);
                    break;

                case SDLK_KP_3:
                    engine.switchThemeByNumpad(3);
                    break;

                case SDLK_KP_4:
                    engine.switchThemeByNumpad(4);
                    break;

                case SDLK_KP_5:
                    engine.switchThemeByNumpad(5);
                    break;

                case SDLK_KP_6:
                    engine.switchThemeByNumpad(6);
                    break;

                case SDLK_KP_7:
                    engine.switchThemeByNumpad(7);
                    break;

                case SDLK_KP_8:
                    engine.switchThemeByNumpad(8);
                    break;

                case SDLK_KP_9:
                    engine.switchThemeByNumpad(9);
                    break;

                case SDLK_KP_0:
                    engine.switchThemeByNumpad(0);
                    break;

                // Toggle de página de temas (Numpad Enter)
                case SDLK_KP_ENTER:
                    engine.toggleThemePage();
                    break;

                // Cambio de sprite/textura dinámico
                case SDLK_N:
                    engine.switchTexture();
                    break;

                // Control de escala de figura (solo en modo SHAPE)
                case SDLK_KP_PLUS:
                    engine.handleShapeScaleChange(true);  // Aumentar
                    break;

                case SDLK_KP_MINUS:
                    engine.handleShapeScaleChange(false);  // Disminuir
                    break;

                case SDLK_KP_MULTIPLY:
                    engine.resetShapeScale();
                    break;

                case SDLK_KP_DIVIDE:
                    engine.toggleDepthZoom();
                    break;

                // Cambio de número de pelotas (escenarios 1-8)
                case SDLK_1:
                    engine.changeScenario(0, "10 pelotas");
                    break;

                case SDLK_2:
                    engine.changeScenario(1, "50 pelotas");
                    break;

                case SDLK_3:
                    engine.changeScenario(2, "100 pelotas");
                    break;

                case SDLK_4:
                    engine.changeScenario(3, "500 pelotas");
                    break;

                case SDLK_5:
                    engine.changeScenario(4, "1.000 pelotas");
                    break;

                case SDLK_6:
                    engine.changeScenario(5, "5.000 pelotas");
                    break;

                case SDLK_7:
                    engine.changeScenario(6, "10.000 pelotas");
                    break;

                case SDLK_8:
                    engine.changeScenario(7, "50.000 pelotas");
                    break;

                case SDLK_9:
                    if (engine.isCustomScenarioEnabled()) {
                        std::string custom_notif = std::to_string(engine.getCustomScenarioBalls()) + " pelotas";
                        engine.changeScenario(CUSTOM_SCENARIO_IDX, custom_notif.c_str());
                    }
                    break;

                // Controles de zoom dinámico (solo si no estamos en fullscreen)
                case SDLK_F1:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.handleZoomOut();
                    }
                    break;

                case SDLK_F2:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.handleZoomIn();
                    }
                    break;

                // Control de pantalla completa
                case SDLK_F3:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.toggleFullscreen();
                    }
                    break;

                // Modo real fullscreen (cambia resolución interna)
                case SDLK_F4:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.toggleRealFullscreen();
                    }
                    break;

                // Toggle PostFX activo/inactivo
                case SDLK_F5:
                    engine.handlePostFXToggle();
                    break;

                // Toggle escalado entero/estirado (solo en fullscreen F3)
                case SDLK_F6:
                    engine.toggleIntegerScaling();
                    break;

                // Redimensionar campo de juego (tamaño lógico + físico)
                case SDLK_F7:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.fieldSizeDown();
                    }
                    break;

                case SDLK_F8:
                    if (engine.isKioskMode()) {
                        engine.showNotificationForAction(KIOSK_NOTIFICATION_TEXT);
                    } else {
                        engine.fieldSizeUp();
                    }
                    break;

                // Toggle Modo DEMO COMPLETO (auto-play) o Pausar tema dinámico (Shift+D)
                case SDLK_D:
                    // Shift+D = Pausar tema dinámico
                    if ((event.key.mod & SDL_KMOD_SHIFT) != 0u) {
                        engine.pauseDynamicTheme();
                    } else {
                        // D sin Shift = Toggle DEMO ↔ SANDBOX
                        engine.toggleDemoMode();
                    }
                    break;

                // Toggle Modo DEMO LITE (solo física/figuras)
                case SDLK_L:
                    engine.toggleDemoLiteMode();
                    break;

                // Toggle Modo LOGO (easter egg - marca de agua)
                case SDLK_K:
                    engine.toggleLogoMode();
                    break;

                // Ciclar presets PostFX (vinyeta/scanlines/cromàtica/complet/desactivat)
                case SDLK_X:
                    engine.handlePostFXCycle();
                    break;

                // Toggle Debug Display (movido de H a F12)
                case SDLK_F12:
                    engine.toggleDebug();
                    break;
            }
        }
    }

    return false;  // No se solicitó salida
}
