// Сначала X11 заголовки
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>

// Отменяем конфликтующие макросы X11 ПОСЛЕ их использования
#undef Status
#undef Bool
#undef None
#undef KeyPress
#undef KeyRelease
#undef FocusIn
#undef FocusOut
#undef FontChange
#undef Expose
#undef CursorShape
#undef Unsorted

// Теперь Qt заголовки
#include <QDebug>
#include "hotkeymanager.h"

HotkeyManager::HotkeyManager(QObject *parent)
    : QThread(parent), display(nullptr), root(0), running(false)
{
}

HotkeyManager::~HotkeyManager()
{
    unregisterHotkey();
}

bool HotkeyManager::registerHotkey()
{
    display = XOpenDisplay(nullptr);
    if (!display) {
        qWarning() << "Cannot open X display";
        return false;
    }

    root = DefaultRootWindow(display);
    
    // Получаем коды клавиш
    keycode_p = XKeysymToKeycode(display, XK_p);
    keycode_ctrl = XKeysymToKeycode(display, XK_Control_L);
    keycode_super = XKeysymToKeycode(display, XK_Super_L);

    // Регистрируем Win+P (Super+P)
    XGrabKey(display, keycode_p, Mod4Mask, root, 1, GrabModeAsync, GrabModeAsync);
    
    // Регистрируем Ctrl+P
    XGrabKey(display, keycode_p, ControlMask, root, 1, GrabModeAsync, GrabModeAsync);
    
    // Также обрабатываем варианты с NumLock и другими модификаторами
    XGrabKey(display, keycode_p, Mod4Mask | Mod2Mask, root, 1, GrabModeAsync, GrabModeAsync);
    XGrabKey(display, keycode_p, ControlMask | Mod2Mask, root, 1, GrabModeAsync, GrabModeAsync);

    XSelectInput(display, root, KeyPressMask);
    
    qDebug() << "Hotkeys registered: Win+P and Ctrl+P";
    
    running = true;
    start();
    
    return true;
}

void HotkeyManager::unregisterHotkey()
{
    running = false;
    
    if (display) {
        XUngrabKey(display, keycode_p, Mod4Mask, root);
        XUngrabKey(display, keycode_p, ControlMask, root);
        XUngrabKey(display, keycode_p, Mod4Mask | Mod2Mask, root);
        XUngrabKey(display, keycode_p, ControlMask | Mod2Mask, root);
        XCloseDisplay(display);
        display = nullptr;
    }
    
    if (isRunning()) {
        quit();
        wait();
    }
}

void HotkeyManager::run()
{
    if (!display) {
        return;
    }

    XEvent event;
    
    while (running) {
        // Ждём событий с таймаутом
        if (XPending(display) > 0) {
            XNextEvent(display, &event);
            
            // KeyPress был #undef'нут, используем числовое значение
            if (event.type == 2) { // 2 = KeyPress в X11
                XKeyEvent *keyEvent = (XKeyEvent*)&event;
                
                // Проверяем Win+P или Ctrl+P
                if (keyEvent->keycode == keycode_p) {
                    unsigned int cleanMask = keyEvent->state & ~(Mod2Mask | LockMask);
                    
                    if (cleanMask == Mod4Mask || cleanMask == ControlMask) {
                        qDebug() << "Hotkey detected!";
                        emit hotkeyPressed();
                    }
                }
            }
        } else {
            // Небольшая задержка чтобы не загружать CPU
            msleep(10);
        }
    }
}
