#include "thememanager.h"

#include <QApplication>
#include <QFile>
#include <QJsonDocument>
#include <QMetaEnum>
#include <cmath>

static const QByteArray defaultConfig = R"Raw(
{
  "color_mode": {
    "light": {
   
    },
    "dark": {
     
    }
  },
  "size_mode": {
    "small": {
      "font_base": "12px",
      "padding_base": "4px",
      "radius_base": "2px",
      "control_height": "20px"
    },
    "medium": {
      "font_base": "14px",
      "padding_base": "8px",
      "radius_base": "4px",
      "control_height": "28px"
    },
    "large": {
      "font_base": "16px",
      "padding_base": "12px",
      "radius_base": "6px",
      "control_height": "36px"
    }
  }
}
)Raw";

static const QByteArray defaultQss = R"Raw(
/********************* 基础样式 *********************/
QWidget {
    font-family: "Segoe UI", "Microsoft YaHei";
    font-size: @font_base;
    color: @colorText;
    background-color: @colorBgContainer;
}

* {
    font-family: "Segoe UI", "Microsoft YaHei";
    font-size: @font_base;
    color: @colorText;
    background-color: @colorBgContainer;
    selection-background-color: @colorPrimaryBg;
    selection-color: @colorPrimaryText;
}

/********************* 窗口栏 *********************/
QWK--WindowBar[bar-active=true] {
    background-color: @colorPrimary;
}

QWK--WindowBar[bar-active=false] {
    background-color: @colorPrimaryBgHover;
}

QWK--WindowBar>QLabel#win-title-label {
    padding: 0;
    border: none;
    color: @colorText;
    background-color: transparent;
    min-height: 28px;
}

/* 系统按钮 */
QWK--WindowBar>QAbstractButton[system-button=true] {
    qproperty-iconSize: 12px 12px;
    min-width: 40px;
    border: none;
    padding: 0;
    background-color: transparent;
}

QWK--WindowBar>QAbstractButton#pin-button {
    qproperty-iconNormal: url(":/window-bar/pin.svg");
    qproperty-iconChecked: url(":/window-bar/pin-fill.svg");
    qproperty-iconSize: 15px 15px;
}

QWK--WindowBar>QAbstractButton#pin-button:hover,
QWK--WindowBar>QAbstractButton#pin-button:pressed {
    background-color: @colorPrimaryBgHover;
}

QWK--WindowBar>QAbstractButton#min-button {
    qproperty-iconNormal: url(":/window-bar/minimize.svg");
}

QWK--WindowBar>QAbstractButton#min-button:hover,
QWK--WindowBar>QAbstractButton#min-button:pressed {
    background-color: @colorPrimaryBgHover;
}

QWK--WindowBar>QAbstractButton#max-button {
    qproperty-iconNormal: url(":/window-bar/maximize.svg");
    qproperty-iconChecked: url(":/window-bar/restore.svg");
}

QWK--WindowBar>QAbstractButton#max-button:hover,
QWK--WindowBar>QAbstractButton#max-button:pressed {
    background-color: @colorPrimaryBgHover;
}

QWK--WindowBar>QAbstractButton#close-button {
    qproperty-iconNormal: url(":/window-bar/close.svg");
}

QWK--WindowBar>QAbstractButton#close-button:hover,
QWK--WindowBar>QAbstractButton#close-button:pressed {
    background-color: @colorError;
}

QWK--WindowBar>QAbstractButton#icon-button {
    qproperty-iconNormal: url(":/app/example.png");
    qproperty-iconSize: 18px 18px;
    min-width: 40px;
    border: none;
    padding: 0;
    background-color: transparent;
}
/********************* 通用控件 *********************/
/* 按钮 */
QPushButton {
    background-color: @colorPrimary;
    color: @colorWhite;
    border: 1px solid @colorPrimaryBorder;
    border-radius: @radius_base;
    padding: @padding_base;
    min-height: @control_height;
    min-width: 80px;
}

QPushButton:hover { 
    background-color: @colorPrimaryHover;
    border-color: @colorPrimaryBorderHover;
}

QPushButton:pressed { 
    background-color: @colorPrimaryActive;
    border-color: @colorPrimaryBorder;
}

QPushButton:disabled { 
    background-color: @colorFillQuaternary;
    border-color: @colorBorderSecondary;
    color: @colorTextQuaternary;
}

/* 标签 */
QLabel {
    background-color: transparent;
    padding: @padding_base;
    color: @colorText;
}

/* 输入控件 */
QLineEdit, QTextEdit, QPlainTextEdit, QComboBox, QSpinBox, QDateTimeEdit {
    background-color: @colorBgContainer;
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
    padding: @padding_base;
    min-height: @control_height;
    color: @colorText;
}

QLineEdit:hover, QTextEdit:hover, QPlainTextEdit:hover,
QComboBox:hover, QSpinBox:hover, QDateTimeEdit:hover {
    border-color: @colorPrimaryHover;
    background-color: @colorBgContainer;
}

QLineEdit:focus, QTextEdit:focus, QPlainTextEdit:focus,
QComboBox:focus, QSpinBox:focus, QDateTimeEdit:focus {
    border-color: @colorPrimary;
    background-color: @colorBgContainer;
}

QComboBox::drop-down {
    subcontrol-origin: padding;
    subcontrol-position: center right;
    width: 20px;
    border-left: 1px solid @colorBorder;
}

QComboBox QAbstractItemView {
    background: @colorBgContainer;
    border: 1px solid @colorBorder;
    selection-background-color: @colorPrimaryBg;
    selection-color: @colorPrimaryText;
}

/* 选择控件 */
QCheckBox, QRadioButton {
    background-color: transparent;
    color: @colorText;
}

QCheckBox::indicator, QRadioButton::indicator {
    width: 16px;
    height: 16px;
}

QCheckBox::indicator {
    border: 1px solid @colorBorder;
    border-radius: @radius_small;
    background: @colorBgContainer;
}

QCheckBox::indicator:checked {
    background-color: @colorPrimary;
    border-color: @colorPrimary;
    image: url(":/theme/checked.svg");
}

QCheckBox:disabled { 
    color: @colorTextQuaternary;
}

QRadioButton::indicator {
    border: 1px solid @colorBorder;
    border-radius: 8px;
    background: @colorBgContainer;
}

QRadioButton::indicator:checked {
    background-color: @colorPrimary;
    border-color: @colorPrimary;
    image: url(":/theme/radio-checked.svg");
}

QRadioButton:disabled { 
    color: @colorTextQuaternary;
}

/********************* 复杂控件 *********************/
/* 选项卡 */
QTabWidget::pane {
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
}

QTabBar::tab {
    background: @colorBgContainer;
    border: 1px solid transparent;
    padding: @padding_base;
    margin-right: 4px;
    color: @colorText;
}

QTabBar::tab:selected {
    background: @colorPrimaryBg;
    border-bottom: 2px solid @colorPrimary;
    color: @colorPrimaryText;
}

QTabBar::tab:hover {
    background: @colorPrimaryBgHover;
}

/* 滚动条 */
/* 滚动条整体 */
QScrollBar:vertical {
    background: @colorFillQuaternary;  /* 滚动条轨道背景 */
    width: 10px;                       /* 垂直滚动条宽度 */
    margin: 10px 0 10px 0;             /* 上下留白 */
}
QScrollBar:horizontal {
    background: @colorFillQuaternary;  /* 滚动条轨道背景 */
    height: 10px;                      /* 水平滚动条高度 */
    margin: 0 10px 0 10px;             /* 左右留白 */
}

/* 滑块（Handle） */
QScrollBar::handle:vertical {
    background: #eaeaea;                 /* 滑块颜色 */
    min-height: 30px;                  /* 垂直滑块最小高度（重要！） */
    border-radius: 5px;                /* 可选圆角 */
}
QScrollBar::handle:horizontal {
    background: #eaeaea;                 /* 滑块颜色 */
    min-width: 30px;                   /* 水平滑块最小宽度（重要！） */
    border-radius: 5px;                /* 可选圆角 */
}

/* 滑块悬停/按下效果 */
QScrollBar::handle:vertical:hover,
QScrollBar::handle:horizontal:hover {
    background: #b0b0b0;               /* 悬停颜色 */
}
QScrollBar::handle:vertical:pressed,
QScrollBar::handle:horizontal:pressed {
    background: #b0b0b0;               /* 按下颜色 */
}

/* 上下/左右箭头按钮（隐藏箭头） */
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical,
QScrollBar::add-line:horizontal,
QScrollBar::sub-line:horizontal {
    background: none;                  /* 隐藏箭头按钮背景 */
    border: none;                      /* 移除边框 */
    height: 0;                         /* 垂直箭头高度设为0 */
    width: 0;                          /* 水平箭头宽度设为0 */
}

/* 滚动条边缘的空白区域（Add-Page/Sub-Page） */
QScrollBar::add-page:vertical,
QScrollBar::sub-page:vertical,
QScrollBar::add-page:horizontal,
QScrollBar::sub-page:horizontal {
    background: none;                  /* 移除默认灰色背景 */
}







/* 树形视图 */
QTreeView {
    show-decoration-selected: 1;
    alternate-background-color: @colorBgContainer;
}

QTreeView::item:hover { 
    background: @colorPrimaryBgHover;
}

QTreeView::item:selected { 
    background: @colorPrimaryBg;
    color: @colorPrimaryText;
}
/********************* 列表视图 *********************/
QListView {
    outline: none;
    background-color: @colorBgContainer;
    alternate-background-color: @colorFillQuaternary;
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
    padding: 2px;
}

QListView::item {
    border-radius: @radius_small;
    padding: @padding_base;
    margin: 1px;
}

QListView::item:hover {
    background: @colorPrimaryBgHover;
}

QListView::item:selected {
    background: @colorPrimaryBg;
    color: @colorPrimaryText;
}

QListView::item:selected:active {
    background: @colorPrimaryBg;
    color: @colorPrimaryText;
}

QListView::item:selected:!active {
    background: @colorFillSecondary;
    color: @colorTextSecondary;
}

/********************* 分组框 *********************/
QGroupBox {
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
    margin-top: 16px;
    padding-top: 20px;
}

QGroupBox::title {
    subcontrol-origin: margin;
    subcontrol-position: top left;
    padding: 0 4px;
    color: @colorTextSecondary;
    left: 12px;
}
QGroupBox {
    background-color: transparent;
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
    margin-top: 1ex;
}

/********************* 滑块控件 *********************/
QSlider::groove:horizontal {
    height: 4px;
    background: @colorFillQuaternary;
    border-radius: 2px;
}

QSlider::handle:horizontal {
    width: 16px;
    margin: -6px 0;
    background: @colorPrimary;
    border-radius: 8px;
}

QSlider::add-page:horizontal { 
    background: @colorFillQuaternary;
}

QSlider::sub-page:horizontal { 
    background: @colorPrimary;
}

/********************* 进度条 *********************/
QProgressBar {
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
    background: @colorFillQuaternary;
    text-align: center;
    color: @colorText;
    padding: 1px;
    min-height: 10px;
}

QProgressBar::chunk {
    background: @colorPrimary;
    border-radius: calc(@radius_base - 1px);
}

/********************* 菜单控件 *********************/
QMenu {
    background: @colorBgContainer;
    border: 1px solid @colorBorder;
    padding: 4px;
}

QMenu::item {
    padding: 6px 24px;
    margin: 2px;
    border-radius: @radius_small;
}

QMenu::item:selected { 
    background: @colorPrimaryBg;
    color: @colorPrimaryText;
}

QMenu::separator { 
    height: 1px; 
    background: @colorBorder;
}

/********************* 表格控件 *********************/
QHeaderView::section {
    background: @colorBgContainer;
    padding: 4px;
    border: 1px solid @colorBorder;
}

QTableView QTableCornerButton::section {
    background: @colorBgContainer;
    border: 1px solid @colorBorder;
}

/********************* 工具栏 *********************/
QToolBar {
    background: @colorBgContainer;
    border-bottom: 1px solid @colorBorder;
    spacing: 4px;
    padding: 4px;
}

QToolBar::separator {
    width: 1px;
    background: @colorBorder;
    margin: 0 4px;
}

/********************* 对话框 *********************/
QDialog {
    background: @colorBgContainer;
    border: 1px solid @colorBorder;
    border-radius: @radius_base;
}

QMessageBox QLabel#qt_msgbox_label { 
    color: @colorText;
    padding: 12px;
}

QMessageBox QPushButton {
    min-width: 80px;
    margin: 4px;
}

/********************* 工具提示 *********************/
QToolTip {
    color: @colorText;
    background-color: @colorBgContainer;
    border: 1px solid @colorBorder;
    border-radius: @radius_small;
    padding: 4px 8px;
}

/********************* 特殊状态 *********************/
/* 错误状态 */
.error-border { 
    border: 1px solid @colorError !important;
}

.error-text { 
    color: @colorError !important;
}

/* 禁用状态 */
.disabled-text { 
    color: @colorTextQuaternary;
}

.disabled-bg { 
    background-color: @colorFillQuaternary;
}

/* 链接样式 */
QLabel[link="true"] { 
    color: @colorLink;
}

QLabel[link="true"]:hover { 
    color: @colorLinkHover;
}

/********************* 动态尺寸 *********************/
.small {
    font-size: 12px;
    padding: 4px;
    qproperty-iconSize: 16px;
}

.medium {
    font-size: 14px;
    padding: 8px;
    qproperty-iconSize: 20px;
}

.large {
    font-size: 16px;
    padding: 12px;
    qproperty-iconSize: 24px;
}

/********************* 工具按钮 *********************/
QToolButton {
    padding: 4px;
    border-radius: @radius_small;
    background: transparent;
}

QToolButton:hover { 
    background: @colorPrimaryBgHover;
}

QToolButton:pressed { 
    background: @colorPrimaryBg;
}

/********************* 分割线 *********************/
QSplitter::handle {
    background: @colorBorder;
    margin: 2px;
}

QSplitter::handle:hover { 
    background: @colorPrimary;
}
/********************* 状态栏 *********************/
QStatusBar {
    background-color: @colorBgContainer;
    border-top: 1px solid @colorBorder;
    color: @colorText;
    min-height: 24px;
    padding: 2px 4px;
}

QStatusBar::item {
    border-right: 1px solid @colorBorder;
    margin: 0;
}

/********************* 状态类 *********************/
.active {
    background-color: @colorPrimaryActive;
    color: @colorPrimaryTextActive;
}

.hover {
    background-color: @colorPrimaryBgHover;
    color: @colorPrimaryTextHover;
}
)Raw";

namespace {
const int hueStep = 2;               // 色相阶梯
const double saturationStep = 0.16;  // 饱和度阶梯，浅色部分
const double saturationStep2 = 0.05; // 饱和度阶梯，深色部分
const double brightnessStep1 = 0.05; // 亮度阶梯，浅色部分
const double brightnessStep2 = 0.15; // 亮度阶梯，深色部分
const int lightColorCount = 5;       // 浅色数量，主色上
const int darkColorCount = 4;        // 深色数量，主色下
// 暗色主题颜色映射关系表
const QVector<int> darkColorMap = {7, 6, 5, 5, 5, 5, 4, 3, 2, 1};
const QVector<int> darkMixRatios = {15, 25, 30, 45, 65, 85, 90, 95, 97, 98};
} // namespace
ThemeManager &ThemeManager::instance()
{
    static ThemeManager instance;
    return instance;
}

ThemeManager::ThemeManager(QObject *parent)
    : QObject(parent)
{
    token.colorPrimary = QColor("#1677ff");
    token.colorSuccess = QColor("#52c41a");
    token.colorWarning = QColor("#faad14");
    token.colorError = QColor("#ff4d4f");
    token.colorInfo = QColor("#1677ff");
    token.colorLink = QColor("");
    token.colorTextBase = QColor("");
    token.colorBgBase = QColor("");

    token.fontFamily = QFont();

    // Line
    token.lineWidth = 1;
    token.lineType = "solid";

    // Radius
    token.borderRadius = 6;

    // Size
    token.sizeUnit = 4;
    token.sizeStep = 4;
    token.sizePopupArrow = 16;

    token.controlHeight = 32;

    QJsonDocument doc = QJsonDocument::fromJson(defaultConfig);
    loadConfig(doc.object());
}

void ThemeManager::loadConfig(const QJsonObject &object)
{
    m_colorConfig = object.value("color_mode").toObject();
    m_sizeConfig = object.value("size_mode").toObject();
    generateDerivedColors();
}

void ThemeManager::loadConfig(const QString &configPath)
{
    QFile configFile(configPath);
    if (!configFile.open(QIODevice::ReadOnly))
        return;

    QJsonDocument doc = QJsonDocument::fromJson(configFile.readAll());
    if (doc.isNull() || !doc.isObject()) {
        qWarning() << "Invalid JSON in config file:" << configPath;
        return;
    }

    loadConfig(doc.object());
}

void ThemeManager::applyTheme()
{
    QString qss = loadQssTemplate();
    QString processed = processQss(qss);
    // qDebug().noquote() << "Processed QSS:" << processed; // 输出生成的 QSS

    qApp->setStyleSheet(processed);
    emit themeChanged();
}

QColor ThemeManager::color(const QString &name) const
{
    QMetaEnum metaEnm = QMetaEnum::fromType<ColorToken>();
    bool isok = false;
    int value = metaEnm.keyToValue(name.toUtf8().data(), &isok);
    if (isok) {
        return m_colorTokens.value((ColorToken) value, QColor(Qt::black));
    }
    qDebug() << "no find " << name << m_colorTokens;
    return QColor(Qt::black);
}

QColor ThemeManager::color(ColorToken token) const
{
    return m_colorTokens.value(token, QColor(Qt::black));
}

void ThemeManager::setPrimaryColor(const QColor &color)
{
    if (token.colorPrimary != color && color.isValid()) {
        token.colorPrimary = color;
        generateDerivedColors();
        applyTheme();
    }
}

void ThemeManager::toggleThemeMode()
{
    m_themeMode = (m_themeMode == Light) ? Dark : Light;
    generateDerivedColors();
    applyTheme();
}

ThemeManager::ThemeMode ThemeManager::themeMode() const
{
    return m_themeMode;
}

void ThemeManager::setThemeMode(ThemeMode themeMode)
{
    if (m_themeMode != themeMode) {
        m_themeMode = themeMode;
        generateDerivedColors();
    }
    applyTheme();
}

ThemeManager::SizeMode ThemeManager::sizeMode() const
{
    return m_sizeMode;
}

void ThemeManager::setSizeMode(SizeMode mode)
{
    if (m_sizeMode != mode) {
        m_sizeMode = mode;
        applyTheme();
    }
}

void ThemeManager::generateDerivedColors()
{
    m_colors.clear();

    auto generateColorPalettes = [this](const QColor baseColor) {
        if (!baseColor.isValid()) {
            return QHash<int, QColor>();
        }
        const QVector<QColor> colors = generateAntdPalette(baseColor);
        return QHash<int, QColor>{
            {1, colors[0]},  //
            {2, colors[1]},  //
            {3, colors[2]},  //
            {4, colors[3]},  //
            {5, colors[4]},  //
            {6, colors[5]},  //
            {7, colors[6]},  //
            {8, colors[4]},  //
            {9, colors[5]},  //
            {10, colors[6]}, //
            //{8: colors[7]},
            //{9: colors[8]},
            //{10: colors[9]};
        };
    };
    QString themeKey = (m_themeMode == Light) ? "light" : "dark";
    QJsonObject themeColors = m_colorConfig.value(themeKey).toObject();

    // 加载基础颜色
    for (auto it = themeColors.begin(); it != themeColors.end(); ++it) {
        QColor color(it.value().toString());
        if (color.isValid()) {
            m_colors[it.key()] = color;
        }
    }

    // 创建 类似 antd 的颜色配置
    const auto primaryColors = generateColorPalettes(token.colorPrimary);
    const auto successColors = generateColorPalettes(token.colorSuccess);
    const auto warningColors = generateColorPalettes(token.colorWarning);
    const auto errorColors = generateColorPalettes(token.colorError);
    const auto infoColors = generateColorPalettes(token.colorInfo);
    generateNeutralColorPalettes(token.colorBgBase, token.colorTextBase);

    // Color Link
    auto colorLink = token.colorLink;
    if (!token.colorLink.isValid()) {
        colorLink = token.colorInfo;
    }
    const auto linkColors = generateColorPalettes(colorLink);

    const auto colorErrorBgFilledHover = mixColor(errorColors[1], errorColors[3], 50);

    m_colorTokens[ColorToken::colorPrimaryBg] = primaryColors[1];
    m_colorTokens[ColorToken::colorPrimaryBgHover] = primaryColors[2];
    m_colorTokens[ColorToken::colorPrimaryBorder] = primaryColors[3];
    m_colorTokens[ColorToken::colorPrimaryBorderHover] = primaryColors[4];
    m_colorTokens[ColorToken::colorPrimaryHover] = primaryColors[5];
    m_colorTokens[ColorToken::colorPrimary] = primaryColors[6];
    m_colorTokens[ColorToken::colorPrimaryActive] = primaryColors[7];
    m_colorTokens[ColorToken::colorPrimaryTextHover] = primaryColors[8];
    m_colorTokens[ColorToken::colorPrimaryText] = primaryColors[9];
    m_colorTokens[ColorToken::colorPrimaryTextActive] = primaryColors[10];

    m_colorTokens[ColorToken::colorSuccessBg] = successColors[1];
    m_colorTokens[ColorToken::colorSuccessBgHover] = successColors[2];
    m_colorTokens[ColorToken::colorSuccessBorder] = successColors[3];
    m_colorTokens[ColorToken::colorSuccessBorderHover] = successColors[4];
    m_colorTokens[ColorToken::colorSuccessHover] = successColors[4];
    m_colorTokens[ColorToken::colorSuccess] = successColors[6];
    m_colorTokens[ColorToken::colorSuccessActive] = successColors[7];
    m_colorTokens[ColorToken::colorSuccessTextHover] = successColors[8];
    m_colorTokens[ColorToken::colorSuccessText] = successColors[9];
    m_colorTokens[ColorToken::colorSuccessTextActive] = successColors[10];

    m_colorTokens[ColorToken::colorErrorBg] = errorColors[1];
    m_colorTokens[ColorToken::colorErrorBgHover] = errorColors[2];
    m_colorTokens[ColorToken::colorErrorBgFilledHover] = colorErrorBgFilledHover;
    m_colorTokens[ColorToken::colorErrorBgActive] = errorColors[3];
    m_colorTokens[ColorToken::colorErrorBorder] = errorColors[3];
    m_colorTokens[ColorToken::colorErrorBorderHover] = errorColors[4];
    m_colorTokens[ColorToken::colorErrorHover] = errorColors[5];
    m_colorTokens[ColorToken::colorError] = errorColors[6];
    m_colorTokens[ColorToken::colorErrorActive] = errorColors[7];
    m_colorTokens[ColorToken::colorErrorTextHover] = errorColors[8];
    m_colorTokens[ColorToken::colorErrorText] = errorColors[9];
    m_colorTokens[ColorToken::colorErrorTextActive] = errorColors[10];

    m_colorTokens[ColorToken::colorWarningBg] = warningColors[1];
    m_colorTokens[ColorToken::colorWarningBgHover] = warningColors[2];
    m_colorTokens[ColorToken::colorWarningBorder] = warningColors[3];
    m_colorTokens[ColorToken::colorWarningBorderHover] = warningColors[4];
    m_colorTokens[ColorToken::colorWarningHover] = warningColors[4];
    m_colorTokens[ColorToken::colorWarning] = warningColors[6];
    m_colorTokens[ColorToken::colorWarningActive] = warningColors[7];
    m_colorTokens[ColorToken::colorWarningTextHover] = warningColors[8];
    m_colorTokens[ColorToken::colorWarningText] = warningColors[9];
    m_colorTokens[ColorToken::colorWarningTextActive] = warningColors[10];

    m_colorTokens[ColorToken::colorInfoBg] = infoColors[1];
    m_colorTokens[ColorToken::colorInfoBgHover] = infoColors[2];
    m_colorTokens[ColorToken::colorInfoBorder] = infoColors[3];
    m_colorTokens[ColorToken::colorInfoBorderHover] = infoColors[4];
    m_colorTokens[ColorToken::colorInfoHover] = infoColors[4];
    m_colorTokens[ColorToken::colorInfo] = infoColors[6];
    m_colorTokens[ColorToken::colorInfoActive] = infoColors[7];
    m_colorTokens[ColorToken::colorInfoTextHover] = infoColors[8];
    m_colorTokens[ColorToken::colorInfoText] = infoColors[9];
    m_colorTokens[ColorToken::colorInfoTextActive] = infoColors[10];

    m_colorTokens[ColorToken::colorLinkHover] = linkColors[4];
    m_colorTokens[ColorToken::colorLink] = linkColors[6];
    m_colorTokens[ColorToken::colorLinkActive] = linkColors[7];
    m_colorTokens[ColorToken::colorWhite] = "#fff";

    // init m_color
    QMetaEnum metaEnum = QMetaEnum::fromType<ColorToken>();
    for (auto it = m_colorTokens.constBegin(); it != m_colorTokens.constEnd(); ++it) {
        const char *enumKey = metaEnum.valueToKey(static_cast<int>(it.key()));
        if (enumKey) {
            m_colors.insert(QString(enumKey), it.value());
        } else {
            qWarning() << "Invalid ColorToken value:" << static_cast<int>(it.key());
        }
    }
}
QString ThemeManager::loadQssTemplate() const
{
    return QString::fromUtf8(defaultQss);
}

QString ThemeManager::processQss(const QString &qss) const
{
    QString processed = qss;

    // 第一步：替换尺寸变量（无依赖关系）
    QString sizeKey;
    switch (m_sizeMode) {
    case Small:
        sizeKey = "small";
        break;
    case Medium:
        sizeKey = "medium";
        break;
    case Large:
        sizeKey = "large";
        break;
    }

    QJsonObject sizeValues = m_sizeConfig.value(sizeKey).toObject();
    for (auto it = sizeValues.begin(); it != sizeValues.end(); ++it) {
        processed.replace("@" + it.key(), it.value().toString());
    }

    // 第二步：使用正则表达式替换颜色变量（处理依赖关系）
    static const QRegularExpression varRegex("@([a-zA-Z0-9_]+)");
    QRegularExpressionMatchIterator it = varRegex.globalMatch(processed);

    QSet<QString> replacedVars;
    while (it.hasNext()) {
        QRegularExpressionMatch match = it.next();
        QString varName = match.captured(1);

        if (replacedVars.contains(varName))
            continue;

        if (m_colors.contains(varName)) {
            QColor color = m_colors[varName];
            QString colorStr = color.alpha() == 255 ? color.name()
                                                    : QString("rgba(%1, %2, %3, %4)")
                                                          .arg(color.red())
                                                          .arg(color.green())
                                                          .arg(color.blue())
                                                          .arg(color.alphaF());

            // 使用单词边界确保精确匹配
            processed.replace(QRegularExpression(QString("@%1\\b").arg(varName)), colorStr);
            replacedVars.insert(varName);
        }
    }

    return processed;
}

QVector<QColor> ThemeManager::generateAntdPalette(const QColor &baseColor) const
{
    QVector<QColor> palette;
    QColor base = baseColor.toHsv();
    qreal h, s, v;
    base.getHsvF(&h, &s, &v);
    h = qRound(h * 360);

    auto getHue = [](qreal hsv_h, int i, bool light) -> qreal {
        qreal hue;
        if (qRound(hsv_h) >= 60 && qRound(hsv_h) <= 240) {
            hue = light ? qRound(hsv_h) - hueStep * i : qRound(hsv_h) + hueStep * i;
        } else {
            hue = light ? qRound(hsv_h) + hueStep * i : qRound(hsv_h) - hueStep * i;
        }
        return std::fmod(hue + 360, 360);
    };

    auto getSaturation = [](qreal hsv_s, int i, bool light) -> qreal {
        // 灰色不改变饱和度
        if (qFuzzyIsNull(hsv_s)) {
            return hsv_s;
        }

        qreal saturation;
        if (light) {
            saturation = hsv_s - saturationStep * i;
        } else if (i == darkColorCount) {
            saturation = hsv_s + saturationStep;
        } else {
            saturation = hsv_s + saturationStep2 * i;
        }

        // 边界值修正
        if (saturation > 1) {
            saturation = 1;
        }
        // 第一格的 s 限制在 0.06-0.1 之间
        if (light && i == lightColorCount && saturation > 0.1) {
            saturation = 0.1;
        }
        if (saturation < 0.06) {
            saturation = 0.06;
        }
        return saturation;
    };

    auto getValue = [](qreal hsv_v, int i, bool light) -> qreal {
        qreal value;
        if (light) {
            value = hsv_v + brightnessStep1 * i;
        } else {
            value = hsv_v - brightnessStep2 * i;
        }
        return qBound(0.0, value, 1.0);
    };

    // 生成浅色系
    for (int i = lightColorCount; i > 0; --i) {
        qreal newH = getHue(h, i, true);
        qreal newS = getSaturation(s, i, true);
        qreal newV = getValue(v, i, true);
        palette.append(QColor::fromHsvF(newH / 360.0, newS, newV));
    }

    // 添加主色
    palette.append(baseColor);

    // 生成深色系
    for (int i = 1; i <= darkColorCount; ++i) {
        qreal newH = getHue(h, i, false);
        qreal newS = getSaturation(s, i, false);
        qreal newV = getValue(v, i, false);
        palette.append(QColor::fromHsvF(newH / 360.0, newS, newV));
    }

    // 暗色主题处理
    if (m_themeMode == Dark) {
        return applyDarkMap(palette);
    }

    return palette;
}

QVector<QColor> ThemeManager::applyDarkMap(const QVector<QColor> &palette,
                                           const QColor &backgroundColor) const
{
    QVector<QColor> darkPalette;
    QColor bgColor = backgroundColor;

    if (!bgColor.isValid()) {
        bgColor = QColor("#141414");
    }
    for (int i = 0; i < palette.size(); ++i) {
        darkPalette.append(mixColor(bgColor, palette[darkColorMap[i]], darkMixRatios[i]));
    }
    return darkPalette;
}

void ThemeManager::generateNeutralColorPalettes(const QColor &baseColor, const QColor &textBaseColor)
{
    QColor colorBgBase = baseColor;
    if (!colorBgBase.isValid()) {
        if (m_themeMode == Light) {
            colorBgBase = QColor("#FFFFFFFF");
        } else {
            colorBgBase = QColor("#000");
        }
    }
    QColor colorTextBase = textBaseColor;
    if (!colorTextBase.isValid()) {
        if (m_themeMode == Light) {
            colorTextBase = QColor("#000");
        } else {
            colorTextBase = QColor("#FFFFFFFF");
        }
    }
    m_colorTokens[ColorToken::colorBgBase] = colorBgBase;
    m_colorTokens[ColorToken::colorTextBase] = colorTextBase;

    auto getAlphaColor = [](const QColor &baseColor, qreal alpha) {
        QColor result = baseColor;
        result.setAlphaF(alpha);
        return result;
    };

    auto getSolidColor = [this](const QColor &baseColor, int amount) {
        // if (m_themeMode == Dark) {
        //     return baseColor.darker(amount);
        // } else {
        //     return baseColor.lighter(amount);
        // }
        QColor hsl = baseColor.toHsl();

        qreal h = hsl.hslHueF(); // 0.0 <= hueF < 360.0
        qreal s = hsl.hslSaturationF();
        qreal l = hsl.lightnessF();

        if (m_themeMode == Dark) {
            l = l + amount / 100.0;
            if (l > 1) {
                l = 1;
            }
        } else {
            l = l - amount / 100.0;
            if (l < 0) {
                l = 0;
            }
        }
        return QColor::fromHslF(h, s, l, baseColor.alphaF());
    };

    if (m_themeMode == Dark) {
        m_colorTokens[ColorToken::colorText] = getAlphaColor(colorTextBase, 0.85);
        m_colorTokens[ColorToken::colorTextSecondary] = getAlphaColor(colorTextBase, 0.65);
        m_colorTokens[ColorToken::colorTextTertiary] = getAlphaColor(colorTextBase, 0.45);
        m_colorTokens[ColorToken::colorTextQuaternary] = getAlphaColor(colorTextBase, 0.25);

        m_colorTokens[ColorToken::colorFill] = getAlphaColor(colorTextBase, 0.18);
        m_colorTokens[ColorToken::colorFillSecondary] = getAlphaColor(colorTextBase, 0.12);
        m_colorTokens[ColorToken::colorFillTertiary] = getAlphaColor(colorTextBase, 0.08);
        m_colorTokens[ColorToken::colorFillQuaternary] = getAlphaColor(colorTextBase, 0.04);

        m_colorTokens[ColorToken::colorBgSolid] = getAlphaColor(colorTextBase, 0.95);
        m_colorTokens[ColorToken::colorBgSolidHover] = getAlphaColor(colorTextBase, 1);
        m_colorTokens[ColorToken::colorBgSolidActive] = getAlphaColor(colorTextBase, 0.9);

        m_colorTokens[ColorToken::colorBgElevated] = getSolidColor(colorBgBase, 12);
        m_colorTokens[ColorToken::colorBgContainer] = getSolidColor(colorBgBase, 8);
        m_colorTokens[ColorToken::colorBgLayout] = getSolidColor(colorBgBase, 0);
        m_colorTokens[ColorToken::colorBgSpotlight] = getSolidColor(colorBgBase, 26);
        m_colorTokens[ColorToken::colorBgBlur] = getAlphaColor(colorTextBase, 0.04);

        m_colorTokens[ColorToken::colorBorder] = getSolidColor(colorBgBase, 26);
        m_colorTokens[ColorToken::colorBorderSecondary] = getSolidColor(colorBgBase, 19);
    } else {
        m_colorTokens[ColorToken::colorText] = getAlphaColor(colorTextBase, 0.88);
        m_colorTokens[ColorToken::colorTextSecondary] = getAlphaColor(colorTextBase, 0.65);
        m_colorTokens[ColorToken::colorTextTertiary] = getAlphaColor(colorTextBase, 0.45);
        m_colorTokens[ColorToken::colorTextQuaternary] = getAlphaColor(colorTextBase, 0.25);

        m_colorTokens[ColorToken::colorFill] = getAlphaColor(colorTextBase, 0.15);
        m_colorTokens[ColorToken::colorFillSecondary] = getAlphaColor(colorTextBase, 0.06);
        m_colorTokens[ColorToken::colorFillTertiary] = getAlphaColor(colorTextBase, 0.04);
        m_colorTokens[ColorToken::colorFillQuaternary] = getAlphaColor(colorTextBase, 0.02);

        m_colorTokens[ColorToken::colorBgSolid] = getAlphaColor(colorTextBase, 1);
        m_colorTokens[ColorToken::colorBgSolidHover] = getAlphaColor(colorTextBase, 0.75);
        m_colorTokens[ColorToken::colorBgSolidActive] = getAlphaColor(colorTextBase, 0.95);

        m_colorTokens[ColorToken::colorBgLayout] = getSolidColor(colorBgBase, 4);
        m_colorTokens[ColorToken::colorBgContainer] = getSolidColor(colorBgBase, 0);
        m_colorTokens[ColorToken::colorBgElevated] = getSolidColor(colorBgBase, 0);
        m_colorTokens[ColorToken::colorBgSpotlight] = getAlphaColor(colorTextBase, 0.85);
        m_colorTokens[ColorToken::colorBgBlur] = "transparent";
        m_colorTokens[ColorToken::colorBorder] = getSolidColor(colorBgBase, 15);
        m_colorTokens[ColorToken::colorBorderSecondary] = getSolidColor(colorBgBase, 6);
    }
}

QColor ThemeManager::mixColor(const QColor &base, const QColor &target, int ratio) const
{
    const qreal p = ratio / 100.0;
    qreal r = (base.red() - target.red()) * p + target.red();
    qreal g = (base.green() - target.green()) * p + target.green();
    qreal b = (base.blue() - target.blue()) * p + target.blue();
    return QColor(r, g, b);
}

QMap<ThemeManager::ControlHeightToken, int> ThemeManager::genControlHeight(const SeedTokens &token)
{
    const int controlHeight = token.controlHeight;
    return {
        {controlHeightSM, controlHeight * 0.75},
        {controlHeightXS, controlHeight * 0.5},
        {controlHeightLG, controlHeight * 1.25},
    };
}

QMap<ThemeManager::SizeToken, int> ThemeManager::genSizeMapToken(const SeedTokens &token)
{
    const int sizeUnit = token.sizeUnit;
    const int sizeStep = token.sizeStep;
    const int compactSizeStep = sizeStep - 2;

    return {
        {SizeXXL, sizeUnit * (compactSizeStep + 10)},
        {SizeXL, sizeUnit * (compactSizeStep + 6)},
        {SizeLG, sizeUnit * (compactSizeStep + 2)},
        {SizeMD, sizeUnit * (compactSizeStep + 2)},
        {SizeMS, sizeUnit * (compactSizeStep + 1)},
        {size, sizeUnit * compactSizeStep},
        {SizeSM, sizeUnit * compactSizeStep},
        {SizeXS, sizeUnit * (compactSizeStep - 1)},
        {SizeXXS, sizeUnit * (compactSizeStep - 1)},
    };
}
