#include "displayswitcher.h"
#include <QApplication>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QScreen>
#include <QDebug>
#include <QRegularExpression>

DisplaySwitcher::DisplaySwitcher(QWidget *parent)
    : QWidget(parent), currentSelection(0), dragging(false)
{
    setupUI();
    // Окно без рамки, но можно перетаскивать
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    setAttribute(Qt::WA_TranslucentBackground, false);

    detectDisplays();
}

DisplaySwitcher::~DisplaySwitcher()
{
}

void DisplaySwitcher::setupUI()
{
    mainLayout = new QVBoxLayout(this);
    mainLayout->setSpacing(10);
    mainLayout->setContentsMargins(20, 20, 20, 20);

    titleLabel = new QLabel("madDisplayManager", this);
    titleLabel->setAlignment(Qt::AlignCenter);
    QFont titleFont = titleLabel->font();
    titleFont.setPointSize(14);
    titleFont.setBold(true);
    titleLabel->setFont(titleFont);
    mainLayout->addWidget(titleLabel);

    mainLayout->addSpacing(10);

    btnPCOnly = new QPushButton("Только экран компьютера", this);
    btnDuplicate = new QPushButton("Повторяющийся", this);
    btnExtend = new QPushButton("Расширить", this);
    btnSecondOnly = new QPushButton("Только второй экран", this);
    btnSwapDisplays = new QPushButton("⇄ Поменять местами мониторы", this);

    QList<QPushButton*> buttons = {btnPCOnly, btnDuplicate, btnExtend, btnSecondOnly, btnSwapDisplays};
    for (auto *btn : buttons) {
        btn->setMinimumHeight(50);
        btn->setStyleSheet(
            "QPushButton {"
            "   background-color: #6b1a1a;"
            "   color: white;"
            "   border: 2px solid #8b2a2a;"
            "   border-radius: 5px;"
            "   padding: 10px;"
            "   font-size: 12pt;"
            "}"
            "QPushButton:hover {"
            "   background-color: #8b2a2a;"
            "   border-color: #ab3a3a;"
            "}"
            "QPushButton:focus {"
            "   background-color: #8b2a2a;"
            "   border-color: #cb4a4a;"
            "}"
        );
        mainLayout->addWidget(btn);
    }

    // Добавляем ссылку на сайт
    linkLabel = new QLabel("<a href='https://madmentat.ru' style='color: #ffaaaa; text-decoration: none;'>madmentat.ru</a>", this);
    linkLabel->setOpenExternalLinks(true);
    linkLabel->setAlignment(Qt::AlignCenter);
    mainLayout->addSpacing(5);
    mainLayout->addWidget(linkLabel);

    connect(btnPCOnly, &QPushButton::clicked, this, &DisplaySwitcher::onPCOnlyClicked);
    connect(btnDuplicate, &QPushButton::clicked, this, &DisplaySwitcher::onDuplicateClicked);
    connect(btnExtend, &QPushButton::clicked, this, &DisplaySwitcher::onExtendClicked);
    connect(btnSecondOnly, &QPushButton::clicked, this, &DisplaySwitcher::onSecondOnlyClicked);
    connect(btnSwapDisplays, &QPushButton::clicked, this, &DisplaySwitcher::onSwapDisplaysClicked);

    setStyleSheet(
        "QWidget {"
        "   background-color: #4a0a0a;"
        "   color: white;"
        "}"
        "QLabel {"
        "   color: white;"
        "}"
    );

    setMinimumWidth(400);
    setMaximumWidth(400);
}

QString DisplaySwitcher::detectDisplays()
{
    QProcess process;
    process.start("xrandr", QStringList() << "--query");
    process.waitForFinished();

    QString output = process.readAllStandardOutput();
    QStringList lines = output.split('\n');

    allDisplays.clear();

    for (const QString &line : lines) {
        if (line.contains(" connected")) {
            QRegularExpression re("^(\\S+)\\s+connected");
            QRegularExpressionMatch match = re.match(line);
            if (match.hasMatch()) {
                allDisplays.append(match.captured(1));
            }
        }
    }

    qDebug() << "Detected displays:" << allDisplays;

    if (allDisplays.size() >= 1) {
        primaryDisplay = allDisplays[0];
    }
    if (allDisplays.size() >= 2) {
        secondaryDisplay = allDisplays[1];
    }

    return output;
}

void DisplaySwitcher::executeXrandrCommand(const QString &command)
{
    qDebug() << "Executing:" << command;
    QProcess::execute("/bin/sh", QStringList() << "-c" << command);
    hide();
}

void DisplaySwitcher::onPCOnlyClicked()
{
    if (!primaryDisplay.isEmpty()) {
        QString cmd = QString("xrandr --output %1 --auto").arg(primaryDisplay);
        if (!secondaryDisplay.isEmpty()) {
            cmd += QString(" --output %1 --off").arg(secondaryDisplay);
        }
        executeXrandrCommand(cmd);
    }
}

void DisplaySwitcher::onDuplicateClicked()
{
    if (!primaryDisplay.isEmpty() && !secondaryDisplay.isEmpty()) {
        QString cmd = QString("xrandr --output %1 --auto --output %2 --auto --same-as %1")
                          .arg(primaryDisplay, secondaryDisplay);
        executeXrandrCommand(cmd);
    }
}

void DisplaySwitcher::onExtendClicked()
{
    if (!primaryDisplay.isEmpty() && !secondaryDisplay.isEmpty()) {
        QString cmd = QString("xrandr --output %1 --auto --output %2 --auto --right-of %1")
                          .arg(primaryDisplay, secondaryDisplay);
        executeXrandrCommand(cmd);
    }
}

void DisplaySwitcher::onSecondOnlyClicked()
{
    if (!secondaryDisplay.isEmpty()) {
        QString cmd = QString("xrandr --output %1 --off --output %2 --auto")
                          .arg(primaryDisplay, secondaryDisplay);
        executeXrandrCommand(cmd);
    }
}

void DisplaySwitcher::onSwapDisplaysClicked()
{
    if (allDisplays.size() < 2) {
        qDebug() << "Not enough displays to swap";
        return;
    }

    // Получаем текущие настройки мониторов
    QProcess process;
    process.start("xrandr", QStringList() << "--current");
    process.waitForFinished();
    QString output = process.readAllStandardOutput();

    // Проверяем, какой монитор сейчас активен (первичный)
    QString currentPrimary;
    QString currentSecondary;

    for (const QString &display : allDisplays) {
        if (output.contains(QString("%1 connected primary").arg(display))) {
            currentPrimary = display;
        } else if (output.contains(QString("%1 connected").arg(display))) {
            currentSecondary = display;
        }
    }

    // Если не определили текущие, используем первые два
    if (currentPrimary.isEmpty() && !allDisplays.isEmpty()) {
        currentPrimary = allDisplays[0];
    }
    if (currentSecondary.isEmpty() && allDisplays.size() > 1) {
        currentSecondary = allDisplays[1];
    }

    qDebug() << "Current primary:" << currentPrimary;
    qDebug() << "Current secondary:" << currentSecondary;

    // Определяем, какой монитор должен стать новым первичным
    QString newPrimary;
    QString newSecondary;

    if (!currentSecondary.isEmpty()) {
        // Переключаемся на второй монитор как основной
        newPrimary = currentSecondary;
        newSecondary = currentPrimary;
    } else {
        // Если второго нет, возвращаемся к первому
        newPrimary = currentPrimary;
        newSecondary = "";
    }

    // Строим команду переключения
    QString cmd;

    if (!newSecondary.isEmpty()) {
        // Два активных монитора: делаем newPrimary основным, newSecondary - вторым
        cmd = QString("xrandr --output %1 --auto --primary --output %2 --auto --right-of %1")
                  .arg(newPrimary, newSecondary);
    } else {
        // Только один монитор активен
        cmd = QString("xrandr --output %1 --auto --primary").arg(newPrimary);
        // Выключаем все остальные мониторы
        for (const QString &display : allDisplays) {
            if (display != newPrimary) {
                cmd += QString(" --output %1 --off").arg(display);
            }
        }
    }

    qDebug() << "Swap command:" << cmd;
    executeXrandrCommand(cmd);

    // Обновляем наши внутренние переменные
    primaryDisplay = newPrimary;
    secondaryDisplay = newSecondary;
}

void DisplaySwitcher::showSwitcher()
{
    detectDisplays();
    centerOnScreen();
    show();
    raise();
    activateWindow();
    setFocus();
    currentSelection = 0;
    btnPCOnly->setFocus();
}

void DisplaySwitcher::centerOnScreen()
{
    QScreen *screen = QApplication::primaryScreen();
    QRect screenGeometry = screen->geometry();
    int x = (screenGeometry.width() - width()) / 2;
    int y = (screenGeometry.height() - height()) / 2;
    move(x, y);
}

void DisplaySwitcher::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape) {
        hide();
        return;
    }

    QList<QPushButton*> buttons = {btnPCOnly, btnDuplicate, btnExtend, btnSecondOnly, btnSwapDisplays};

    if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Tab) {
        currentSelection = (currentSelection + 1) % buttons.size();
        buttons[currentSelection]->setFocus();
        event->accept();
        return;
    }

    if (event->key() == Qt::Key_Up) {
        currentSelection = (currentSelection - 1 + buttons.size()) % buttons.size();
        buttons[currentSelection]->setFocus();
        event->accept();
        return;
    }

    if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
        buttons[currentSelection]->click();
        event->accept();
        return;
    }

    QWidget::keyPressEvent(event);
}

void DisplaySwitcher::focusOutEvent(QFocusEvent *event)
{
    Q_UNUSED(event);
    // Можно раскомментировать если хотите автозакрытие при потере фокуса
    // hide();
}

void DisplaySwitcher::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        dragging = true;
        dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft();
        event->accept();
    }
}

void DisplaySwitcher::mouseMoveEvent(QMouseEvent *event)
{
    if (dragging && (event->buttons() & Qt::LeftButton)) {
        move(event->globalPosition().toPoint() - dragPosition);
        event->accept();
    }
}

void DisplaySwitcher::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        dragging = false;
        event->accept();
    }
}
