#include "core/input/mouse.hpp"

#include <iostream>

namespace Mouse {
Uint32 cursor_hide_time = 3000;   // Tiempo en milisegundos para ocultar el cursor
Uint32 last_mouse_move_time = 0;  // Última vez que el ratón se movió
bool cursor_visible = false;      // Estado del cursor (inicia ocult)

// Modo forzado: Usado cuando SDLManager entra en pantalla completa.
// Cuando está activado, el cursor permanece oculto independientemente del movimiento del ratón.
// SDLManager controla esto mediante llamadas a setForceHidden().
bool force_hidden = false;

// Temps de inicialización per ignorar esdeveniments fantasma de SDL
Uint32 initialization_time = 0;
constexpr Uint32 IGNORE_MOTION_DURATION = 1000;  // Ignorar primers 1000ms

void forceHide() {
    // Forçar ocultació sincronitzant state SDL i state intern
    std::cout << "[Mouse::forceHide] Ocultant cursor i sincronitzant state. cursor_visible=" << cursor_visible
              << " -> false" << '\n';
    SDL_HideCursor();
    cursor_visible = false;
    last_mouse_move_time = 0;
    initialization_time = SDL_GetTicks();  // Marcar time per ignorar esdeveniments inicials
    std::cout << "[Mouse::forceHide] Ignorant moviments durante " << IGNORE_MOTION_DURATION << "ms" << '\n';
}

void setForceHidden(bool force) {
    force_hidden = force;

    if (force) {
        // Entrando en modo oculto forzado: ocultar cursor inmediatamente
        SDL_HideCursor();
        cursor_visible = false;
    } else {
        // Saliendo de modo oculto forzado: NO mostrar cursor automáticamente
        // El cursor permanece oculto hasta que haya movimiento de ratón (handleEvent)
        last_mouse_move_time = SDL_GetTicks();  // Resetear temporizador
        // cursor_visible permanece false - handleEvent lo cambiará al detectar movimiento
    }
}

auto isForceHidden() -> bool {
    return force_hidden;
}

void handleEvent(const SDL_Event& event) {
    // CRÍTICO: Si estamos en modo forzado, ignorar todos los eventos del ratón
    if (force_hidden) {
        return;  // Salir temprano - no procesar ningún evento
    }

    // MODO NORMAL: Mostrar cursor al mover el ratón
    if (event.type == SDL_EVENT_MOUSE_MOTION) {
        Uint32 current_time = SDL_GetTicks();

        // Ignorar esdeveniments fantasma de SDL durante el període inicial
        if (initialization_time > 0 && (current_time - initialization_time < IGNORE_MOTION_DURATION)) {
            std::cout << "[Mouse::handleEvent] Ignorant movement fantasma de SDL. time=" << current_time
                      << " (inicialización hace " << (current_time - initialization_time) << "ms)" << '\n';
            return;
        }

        last_mouse_move_time = current_time;
        if (!cursor_visible) {
            std::cout << "[Mouse::handleEvent] Mostrant cursor per movement REAL. time=" << last_mouse_move_time << '\n';
            SDL_ShowCursor();
            cursor_visible = true;
        }
    }
}

void updateCursorVisibility() {
    // CRÍTICO: Si estamos en modo forzado, no aplicar lógica de timeout
    if (force_hidden) {
        return;  // Salir temprano - el cursor permanece oculto
    }

    // MODO NORMAL: Auto-ocultar basado en timeout
    Uint32 current_time = SDL_GetTicks();
    if (cursor_visible && (current_time - last_mouse_move_time > cursor_hide_time)) {
        std::cout << "[Mouse::updateCursorVisibility] Ocultant cursor per timeout. current=" << current_time
                  << " last=" << last_mouse_move_time << " diff=" << (current_time - last_mouse_move_time) << '\n';
        SDL_HideCursor();
        cursor_visible = false;
    }
}
}  // namespace Mouse
