#include "ostree-watermark.h"
#include <QApplication>
#include <QDir>
#include <QFileSystemWatcher>
#include <QPainter>
#include <QPixmap>
#include <QRandomGenerator>
#include <QScreen>
#include <QSettings>

#define INIT_FONT_SIZE 20
#define INIT_FONT_COLOR "red"
#define OTSREE_CONF "/ostree/pkgs/ostree-ovl.conf"

WaterMark::WaterMark(QWidget *parent)
    : QWidget(parent)
{
    setWindowOpacity(1.0);
    setAutoFillBackground(false);
    setAttribute(Qt::WA_TransparentForMouseEvents);
    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);

    configFilePath = QDir::homePath() + "/.config/mm-watermark.conf";

    initConfig();

    pngFilePath = QDir::homePath() + "/.config/mm-watermark.png";
    saveWatermarkToImage(pngFilePath, fontColor, fontSize, fontPos);

    waterMarkInterface = new QDBusInterface("org.ukui.KWin", "/Watermark", "org.ukui.kwin.Watermark");

    listenOstreeConfigChange();

    QDBusMessage message = QDBusMessage::createMethodCall("com.kylin.MaintainMode",
                                                          "/com/kylin/MaintainMode/Object",
                                                          "com.kylin.MaintainMode.interface",
                                                          QStringLiteral("GetBootMode"));
    QDBusReply<QString> reply = QDBusConnection::systemBus().call(message);
    QString currentMode = reply.value();
    qDebug() << reply.value();

    bool success = QDBusConnection::systemBus().connect("com.kylin.MaintainMode",
                                                        "/com/kylin/MaintainMode/Object",
                                                        "com.kylin.MaintainMode.interface",
                                                        QStringLiteral("BootModeChanged"),
                                                        this,
                                                        SLOT(getChangedBootMode(quint32)));
    qDebug() << success;

    QScreen *screen = QGuiApplication::primaryScreen();
    connect(screen, &QScreen::geometryChanged, this, [this, currentMode]() {
        if (currentMode.compare("normal") == 0)
            return;
        saveWatermarkToImage(pngFilePath, fontColor, fontSize, fontPos);
        waterMarkInterface->call("updateWatermark", QVariant::fromValue(pngFilePath), QVariant::fromValue(qreal(1)));
    });
}

WaterMark::~WaterMark()
{
}

void WaterMark::initConfig()
{
    if (QFile::exists(configFilePath)) {
        fontSize = readConfigFile(configFilePath, "watermark", "fontSize").toInt();
        QString configColor = readConfigFile(configFilePath, "watermark", "fontColor").toString();
        fontColor = QColor(configColor);
        QString configPos = readConfigFile(configFilePath, "watermark", "fontPos").toString();
        fontPos = stringToWaterMarkPosition(configPos);
    } else {
        fontSize = INIT_FONT_SIZE;
        fontColor = INIT_FONT_COLOR;
        fontPos = WaterMark::BottomRight;
    }

    qDebug() << "Watermark init fontSize " << fontSize << "fontColor" << fontColor << "fontPos" << waterMarkPositionToString(fontPos);
}

QVariant WaterMark::readConfigFile(const QString &filepath, const QString &group, const QString &key)
{
    QSettings settings(filepath, QSettings::IniFormat);
    settings.beginGroup(group);
    QVariant ans = settings.value(key);
    settings.endGroup();
    return ans;
}

void WaterMark::writeConfigFile(const QString &filepath, const QString &group, const QString &key, const QVariant &value)
{
    QSettings settings(filepath, QSettings::IniFormat);
    settings.beginGroup(group);
    settings.setValue(key, value);
    settings.endGroup();
    settings.sync(); // 确保立即写入磁盘
}

QString WaterMark::waterMarkPositionToString(WaterMark::waterMarkPosition pos)
{
    switch (pos) {
    case WaterMark::TopLeft:
        return "TopLeft";
    case WaterMark::TopRight:
        return "TopRight";
    case WaterMark::BottomLeft:
        return "BottomLeft";
    case WaterMark::BottomRight:
        return "BottomRight";
    case WaterMark::CenterTop:
        return "CenterTop";
    case WaterMark::CenterBottom:
        return "CenterBottom";
    default:
        return "BottomRight";
    }
}

WaterMark::waterMarkPosition WaterMark::stringToWaterMarkPosition(const QString &str)
{
    if (str == "TopLeft")
        return WaterMark::TopLeft;
    else if (str == "TopRight")
        return WaterMark::TopRight;
    else if (str == "BottomLeft")
        return WaterMark::BottomLeft;
    else if (str == "BottomRight")
        return WaterMark::BottomRight;
    else if (str == "CenterTop")
        return WaterMark::CenterTop;
    else if (str == "CenterBottom")
        return WaterMark::CenterBottom;
    else
        return WaterMark::BottomRight; // 默认值或你可以抛异常
}

void WaterMark::calculateScreen()
{
    QScreen *primaryScreen = QGuiApplication::primaryScreen();
    if (primaryScreen) {
        primaryScreenGeometry = primaryScreen->geometry(); // 屏幕几何
    }
    fullScreenGeometry = QRect();
    for (QScreen *screen : QGuiApplication::screens()) {
        fullScreenGeometry = fullScreenGeometry.united(screen->geometry());
    }

    setGeometry(fullScreenGeometry);
}

void WaterMark::saveWatermarkToImage(const QString &filePath, QColor color, int font, WaterMark::waterMarkPosition pos)
{
    calculateScreen();
    QPixmap pixmap(fullScreenGeometry.size());
    pixmap.fill(Qt::transparent); // 设置为透明背景

    QPainter painter(&pixmap);

    QString text;
    QString lang = QLocale::system().name(); // e.g. "zh_CN", "bo_CN", "mn_MN"
    if (lang.startsWith("zh_CN")) {
        text = "维护模式";
    } else if (lang.startsWith("zh_HK")) {
        text = "維護模式";
    } else if (lang.startsWith("bo")) {
        text = "སྒྲིག་ལག་ཐབས་ལམ"; // 藏文
    } else if (lang.startsWith("mn")) {
        text = "ᠵᠠᠰᠠᠪᠤᠷ ᠤᠨ ᠬᠡᠷᠡᠭᠡ"; // 蒙古文手写形式
    } else {
        text = "Maintain Mode"; // 默认英文
    }

    QFont vfont;
    vfont.setPointSize(font);
    vfont.setBold(true);
    painter.setFont(vfont);
    painter.setPen(color); // 红色

    // 计算屏幕的中心位置
    calculateShowPosition(pos, vfont, text);

    // 绘制文本
    painter.drawText(fontPosX, fontPosY, text);

    painter.end(); // 完成绘制

    // 保存为图片
    if (!pixmap.save(filePath)) {
        qDebug() << "Failed to save watermark image to:" << filePath;
    } else {
        qDebug() << "Watermark image saved to:" << filePath;
    }
}

void WaterMark::calculateShowPosition(waterMarkPosition position, const QFont &font, QString text)
{
    int margin = 48;
    QFontMetricsF fontMetrics(font);
    qreal font_w = fontMetrics.width(text);
    qreal font_h = fontMetrics.height();

    // 屏幕宽高
    qreal screen_w = fullScreenGeometry.width();
    qreal screen_h = fullScreenGeometry.height();

    switch (position) {
    case TopLeft:
        fontPosX = margin;
        fontPosY = margin + font_h;
        break;
    case TopRight:
        fontPosX = screen_w - font_w - margin;
        fontPosY = margin + font_h;
        break;
    case BottomLeft:
        fontPosX = margin;
        fontPosY = screen_h - font_h - margin;
        break;
    case BottomRight:
        fontPosX = screen_w - font_w - margin;
        fontPosY = screen_h - font_h - margin;
        break;
    case CenterTop:
        fontPosX = (screen_w - font_w) / 2;
        fontPosY = margin + font_h;
        break;
    case CenterBottom:
        fontPosX = (screen_w - font_w) / 2;
        fontPosY = screen_h - font_h - margin;
        break;
    }
}

bool WaterMark::switchModeImmediate()
{
    return m_isSwitchModeImmediate;
}

void WaterMark::switchState(bool changed)
{
    QFile file(OTSREE_CONF);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return;
    }

    QTextStream in(&file);
    QString content = in.readAll();
    QString mode;
    QStringList lines = content.split("\n");
    for (const QString &line : lines) {
        if (!changed && line.startsWith("mode=")) {
            mode = line.mid(5).trimmed();
            break;
        } else if (changed && line.startsWith("next_mode=")) {
            mode = line.mid(10).trimmed();
            break;
        }
    }
    (mode == "maintain") ? open() : close();
}

void WaterMark::getChangedBootMode(qint32 bootMode)
{
    qDebug() << bootMode;
}

void WaterMark::open()
{
    waterMarkInterface->call("updateWatermark", QVariant::fromValue(pngFilePath), QVariant::fromValue(qreal(1)));
}

void WaterMark::close()
{
    waterMarkInterface->call("updateWatermark", QVariant::fromValue(QString()), QVariant::fromValue(qreal(1)));
}

void WaterMark::update(int color, int font_size, int position)
{
    fontSize = font_size;
    fontColor = color == 0 ? QColor(255, 0, 0) : QColor(0, 255, 0);
    // waterMarkPosition pos = position == 0 ? waterMarkPosition::TopLeft : waterMarkPosition::TopRight;
    waterMarkPosition pos = waterMarkPosition::BottomRight;
    if (position == 0) {
        pos = waterMarkPosition::TopLeft;
    } else if (position == 1) {
        pos = waterMarkPosition::TopRight;
    } else {
        pos = waterMarkPosition::BottomRight;
    }
    fontPos = pos;
    // saveWatermarkToImage(filePath);
    saveWatermarkToImage(pngFilePath, fontColor, fontSize, fontPos);

    waterMarkInterface->call("updateWatermark", QVariant::fromValue(pngFilePath), QVariant::fromValue(qreal(1)));

    writeConfigFile(configFilePath, "watermark", "fontSize", fontSize);
    QString configColor = [&]() -> QString {
        for (const QString &name : QColor::colorNames()) {
            if (QColor(name) == fontColor) {
                return name;
            }
        }
        return fontColor.name();
    }();
    writeConfigFile(configFilePath, "watermark", "fontColor", configColor);
    QString configPos = waterMarkPositionToString(fontPos);
    writeConfigFile(configFilePath, "watermark", "fontPos", configPos);
    qDebug() << "Watermark update fontSize " << fontSize << "fontColor" << fontColor << "configPos" << configPos;
}

void WaterMark::listenOstreeConfigChange()
{
    QFile file(OTSREE_CONF);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return;
    }

    QTextStream in(&file);
    QString content = in.readAll();
    QString switchMode;
    QStringList lines = content.split("\n");
    for (const QString &line : lines) {
        if (line.startsWith("switch_mode_immediate=")) {
            switchMode = line.section('=', 1).trimmed();
            break;
        }
    }

    if (switchMode.compare("true", Qt::CaseInsensitive) == 0) {
        m_isSwitchModeImmediate = true;
    } else {
        qDebug() << "switch_mode_immediate is false, return.";
        return;
    }

    QFileSystemWatcher *ostreeConfigWatcher = new QFileSystemWatcher();
    ostreeConfigWatcher->addPath(OTSREE_CONF);
    connect(ostreeConfigWatcher, &QFileSystemWatcher::fileChanged, this, [ostreeConfigWatcher, this]() {
        switchState(true);
        listenOstreeConfigChange();
        ostreeConfigWatcher->deleteLater();
    });
}
