#include "jsonhighlighter.h"
#include <QDebug>

JsonHighlighter::JsonHighlighter(QTextDocument *parent) : QSyntaxHighlighter(parent), m_document(nullptr) {
    // 关键字的颜色规则
    addRule(QRegExp("\"[^\"]*\""), Qt::darkGreen);   // 字符串
    addRule(QRegExp("\\b(true|false|null)\\b"), Qt::darkBlue);  // 字面量
    addRule(QRegExp("[{}\\[\\]]"), Qt::darkMagenta); // 括号
    addRule(QRegExp(":"), Qt::darkRed);              // 冒号
    // 初始化错误格式
    m_errorFormat.setUnderlineColor(Qt::red);
    m_errorFormat.setUnderlineStyle(QTextCharFormat::WaveUnderline);
    m_errorFormat.setForeground(Qt::red); // 可选：文字颜色
}
void JsonHighlighter::addRule(const QRegExp &pattern, const QColor &color) {
    HighlightRule rule;
    rule.pattern = pattern;
    rule.format.setForeground(color);
    rule.format.setFontWeight(QFont::Bold);
    rules.append(rule);
}
void JsonHighlighter::highlightBlock(const QString &text) {
    for (const auto &rule : rules) {
        QRegExp expression(rule.pattern);
        int index = expression.indexIn(text);
        while (index >= 0) {
            int length = expression.matchedLength();
            setFormat(index, length, rule.format);
            index = expression.indexIn(text, index + length);
        }
    }
    // 步骤 2: 检测语法错误
    // detectJsonErrors(text);
}
// 检测错误并标记
void JsonHighlighter::detectJsonErrors(const QString& text) {
    QStack<QChar> stack;
    int pos = 0;
    while (pos < text.length()) {
        QChar ch = text.at(pos);

        if (ch == '\"') {
            if (stack.isEmpty() || stack.top() != '\"') {
                // 开始一个新的字符串
                stack.push('\"');
            } else {
                // 闭合字符串
                stack.pop();
            }
            pos++;
        } else if (ch == '\\') {
            // 跳过转义字符后的字符
            pos += 2;
        } else if (!stack.isEmpty() && stack.top() == '\"') {
            // 在字符串内部，忽略其他字符
            pos++;
        } else if (ch == '{' || ch == '[') {
            stack.push(ch);
            pos++;
        } else if (ch == '}' || ch == ']') {
            if (!stack.isEmpty()) {
                QChar top = stack.top();
                if ((top == '{' && ch == '}') || (top == '[' && ch == ']')) {
                    stack.pop();
                } else {
                    // 不匹配的括号，标记错误
                    setFormat(pos, 1, m_errorFormat);
                }
            } else {
                // 没有对应的开始括号，标记错误
                setFormat(pos, 1, m_errorFormat);
            }
            pos++;
        } else {
            pos++;
        }
    }

    // 检查未闭合的引号、括号和大括号
    while (!stack.isEmpty()) {
        QChar top = stack.top();
        if (top == '\"') {
            // 未闭合的字符串，标记错误
            int start = text.lastIndexOf('\"', pos - 1);
            if (start != -1) {
                setFormat(start, text.length() - start, m_errorFormat);
            }
        } else if (top == '{' || top == '[') {
            // 未闭合的括号或大括号，标记错误
            int start = text.lastIndexOf(top, pos - 1);
            if (start != -1) {
                setFormat(start, 1, m_errorFormat);
            }
        }
        stack.pop();
    }
}


QQuickTextDocument* JsonHighlighter::document() const {
    return m_document;
}
void JsonHighlighter::setDocument(QQuickTextDocument* doc) {
    if (m_document != doc) {
        m_document = doc;
        if (doc) {
            QSyntaxHighlighter::setDocument(doc->textDocument());
        } else {
            QSyntaxHighlighter::setDocument(nullptr);
        }
        emit documentChanged();
    }
}

QString JsonProcessor::formatJson(const QString &rawJson) {
    QJsonDocument doc = QJsonDocument::fromJson(rawJson.toUtf8());
    if (doc.isNull()) return "";
    return QString::fromUtf8(doc.toJson(QJsonDocument::Indented));
}

QVariantMap JsonProcessor::validateJson(const QString &json) {
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8(), &error);
    QVariantMap result;

    if (error.error != QJsonParseError::NoError) {
        result["hasError"] = true;
        result["errorOffset"] = error.offset;  // 错误位置
        result["errorMessage"] = error.errorString(); // 错误描述
    } else {
        result["hasError"] = false;
    }
    return result;
}
