#include "toneadditemdialog.h"
#include "ui_toneadditemdialog.h"

#include <QDragEnterEvent>
#include <QMimeData>
#include <QUrl>
#include <QFileInfo>
#include <QDebug>
#include <QToolButton>
#include <QTimer>
#include <QPushButton>
#include <QJsonArray>
#include <QFileDialog>
#include <QStandardPaths>
#include "custommessagebox.h"
#include "../global/doctemplatemanager.h"
#include "../global/filedialoghelper.h"
// 目标文件后缀集合
const QSet<QString> targetSuffixes = {
    "doc", "docx", "pdf"
};

ToneAddItemDialog::ToneAddItemDialog(QWidget *parent) : QDialog(parent)
  , ui(new Ui::ToneAddItemDialog)
{
    ui->setupUi(this);
    mDocumentModel = new DocumentListModel();
    mDocumentReader = new DocumentReader();
    // 创建段落管理器
    m_paragraphManager = new ParagraphManager(this);
    m_paragraphManager->loadParagraphs(":/template/paragraphs.json");

    initUI();
    initConnect();
    //this->setProperty("ukui_surface_no_titlebar", true);

    // 创建文档解析线程
    mDocParseThread = new DocParseThread(this);

    ui->pushButton_parse->setEnabled(false);

    // 连接信号槽
    connect(mDocParseThread, &DocParseThread::receivedMessage,
            this, &ToneAddItemDialog::onRecParseMsg);
    connect(mDocParseThread, &DocParseThread::receivedError,
            this, &ToneAddItemDialog::onRecParseError);

    mParseTimer = new QTimer(this);
    mParseTimer->setSingleShot(true);
    connect(mParseTimer, &QTimer::timeout, this, &ToneAddItemDialog::onParseTimeout);
}

ToneAddItemDialog::~ToneAddItemDialog()
{
    delete ui;
    if (mDocParseThread)
    {
        mDocParseThread->quit();
        mDocParseThread->wait();
    }
}

void ToneAddItemDialog::initUI()
{
    ui->pushButton_parse->setProperty("isImportant", true);
    ui->pushButton_confirm->setProperty("isImportant", true);
    mDelegate = new DocumentItemDelegate(mDocumentModel);
    ui->listview->setModel(mDocumentModel);
    ui->listview->setItemDelegate(mDelegate);

    ui->label_parsing_error->setVisible(false);
    return;
}

bool ToneAddItemDialog::canEnableNextButton()
{
    // 只要有文件就可以下一步
    return mDocumentModel->getDocumentCount() > 0;
}

void ToneAddItemDialog::parsingTone()
{
    mRecvMsg.clear();
    QList<DocumentItem*> items = mDocumentModel->getDocumentList();
    DocumentItem* document = items.at(0);
    QIcon icon = QIcon::fromTheme(document->documentType, QIcon::fromTheme("text-x-generic"));
    ui->label_parsing_icon->setPixmap(QPixmap(icon.pixmap(48, 48)));
    ui->label_parsing_name->setText(document->documentName);

    QString content = mDocumentReader->getAllText(document->documentPath);

    // 获取参考文本
    QString referenceText = ui->textEdit->toPlainText();
    if (referenceText.isEmpty()) {
        referenceText = m_paragraphManager->getNextParagraph();
    }

    // 构造发送消息的JSON格式
    QJsonObject messageObj;
    messageObj["msgType"] = "sendChatMsg";

    QString promptTemplate =
            "请严格按以下JSON格式解析文档内容并返回，不要返回其他任何内容：\n\n"
            "{\n"
            "  \"tone_name\": \"语气风格名称\",\n"
            "  \"tone_prompt\": \"语气风格指令\",\n"
            "  \"target_text\": \"根据语气风格和参考原始文本生成的目标文章\",\n"
            "  \"id\": \"Tone\"\n"
            "}\n\n"
            "要求：\n"
            "1. tone_name：提炼文章的语气风格，模型解析自动生成，长度不超过32个字，越少越好，能精准概括即可\n"
            "2. tone_prompt：提炼文章的语气风格指令，长度不超过1000个字，越少越好，能精准概括即可\n"
            "3. target_text：根据参考原始文本和解析出的语气风格，生成一篇目标文章，字数同样参考原始文本，不要包含任何格式，纯文本排版即可\n"
            "需要解析的文档内容如下：\n\n"
            + content +
            "\n\n参考原始文本：\n" + referenceText;

    QJsonObject msgBody;
    msgBody["inputMsg"] = promptTemplate;

    messageObj["msgBody"] = msgBody;

    QJsonDocument doc(messageObj);
    QString jsonString = doc.toJson(QJsonDocument::Compact);

    // 发送消息到工作线程
    mDocParseThread->sendMessage(jsonString);
    mParseTimer->start(60000);
    return;
}

void ToneAddItemDialog::onRecParseMsg(const QString message)
{
    // 解析收到的JSON消息
    QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
    if (doc.isNull())
    {
        qDebug() << "Failed to parse JSON message";
        return;
    }

    QJsonObject rootObj = doc.object();
    QString msgType = rootObj["msgType"].toString();
    if (msgType != "recvChatMsg")
    {
        return;
    }

    QJsonObject msgBody = rootObj["msgBody"].toObject();
    QString recvMsg = msgBody["recvMsg"].toString();
    bool isEnd = msgBody["isEnd"].toBool();
    mRecvMsg.append(recvMsg);

    QTextCursor cursor = ui->textEdit_target->textCursor();
    cursor.insertText(recvMsg);

    if(isEnd)
    {
        mParseTimer->stop();
        qDebug()<<"recvChatMsg:"<<mRecvMsg;
        QJsonDocument doc = QJsonDocument::fromJson(mRecvMsg.toUtf8());
        QJsonObject root;
        if (doc.isNull())
        {
            root = extractJsonFromString(mRecvMsg);
            if(root.isEmpty())
            {
                if(ui->stackedWidget_steps->currentWidget() == ui->page_parse)
                {
                    ui->pushButton_confirm->setEnabled(true);
                }
                return; // 解析失败
            }
        }
        else
        {
            root = doc.object();
        }

        QString id = root["id"].toString();

        if(id == "Tone")
        {
            QString toneName;
            QString tonePrompt;
            QString targetText;

            // 修改parseToneResponse函数来解析新的字段
            if(parseToneResponse(root, toneName, tonePrompt, targetText))
            {
                ui->lineEdit_tonestyle_name->setText(toneName);
                //ui->textEdit_tonestyle_prompt->setText(tonePrompt);

                // 获取参考文本
                QString referenceText = ui->textEdit->toPlainText();
                if (referenceText.isEmpty()) {
                    referenceText = m_paragraphManager->getNextParagraph();
                }
                ui->textEdit_original->setText(referenceText);

                // 设置生成的目标文本
                ui->textEdit_target->setText(targetText);

                ui->stackedWidget_steps->setCurrentWidget(ui->page_parse);
                ui->pushButton_confirm->setEnabled(true);
            }
        }
    }
    return;
}

QJsonObject ToneAddItemDialog::extractJsonFromString(const QString& input)
{
    if (input.isEmpty())
    {
        qDebug() << "Input is empty";
        return QJsonObject();
    }

    QString jsonStr = input.trimmed();

    // 检查是否包含Markdown标记
    bool hasMarkdown = jsonStr.contains("```json") || jsonStr.contains("```");
    qDebug() << "Has markdown:" << hasMarkdown;

    if (hasMarkdown)
    {
        // 方法1：尝试提取```json内容
        int startIdx = jsonStr.indexOf("```json");
        if (startIdx != -1)
        {
            startIdx += 7; // 跳过"```json"
            int endIdx = jsonStr.lastIndexOf("```");
            if (endIdx > startIdx)
            {
                jsonStr = jsonStr.mid(startIdx, endIdx - startIdx).trimmed();
            }
        }
        else
        {
            // 方法2：尝试提取```内容
            startIdx = jsonStr.indexOf("```");
            if (startIdx != -1)
            {
                startIdx += 3; // 跳过"```"
                int endIdx = jsonStr.lastIndexOf("```");
                if (endIdx > startIdx)
                {
                    jsonStr = jsonStr.mid(startIdx, endIdx - startIdx).trimmed();
                }
            }
        }
    }

    // 再次修剪字符串
    jsonStr = jsonStr.trimmed();

    // 检查是否仍然包含```标记（可能是残留的）
    if (jsonStr.contains("```"))
    {
        // 移除可能残留的标记
        jsonStr.replace("```", "");
        jsonStr = jsonStr.trimmed();
    }

    // 安全检查
    if (jsonStr.isEmpty())
    {
        return QJsonObject();
    }

    // 解析JSON
    QJsonParseError parseError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &parseError);

    if (parseError.error != QJsonParseError::NoError)
    {
        // 尝试更激进的清理
        jsonStr.remove('\n');
        jsonStr.remove('\r');
        jsonStr = jsonStr.trimmed();

        jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &parseError);
        if (parseError.error != QJsonParseError::NoError)
        {
            return QJsonObject();
        }
    }

    if (jsonDoc.isObject())
    {
        QJsonObject result = jsonDoc.object();
        return result;
    }

    return QJsonObject();
}

void ToneAddItemDialog::onRecParseError(const QString message)
{
    mParseTimer->stop();
    if(ui->stackedWidget_steps->currentWidget() == ui->page_parsing)
    {
        ui->label_parsing_tip->setVisible(false);
        ui->label_parsing_error->setVisible(true);
        ui->label_parsing_error->setText(message);

        // 计算文本宽度，决定对齐方式
        QFontMetrics fm(ui->label_parsing_error->font());
        int textWidth = fm.horizontalAdvance(message);

        // 根据文本宽度设置对齐方式
        if (textWidth <= 380)
        {
            // 文本宽度小于等于380px，水平居中
            ui->label_parsing_error->setFixedWidth(360);
            ui->label_parsing_error->setAlignment(Qt::AlignCenter);
        }
        else
        {
            // 文本宽度大于380px，左对齐（换行显示）
            ui->label_parsing_error->setFixedWidth(380);
            ui->label_parsing_error->setAlignment(Qt::AlignLeft | Qt::AlignTop);
        }
    }
    else if(ui->stackedWidget_steps->currentWidget() == ui->page_parse)
    {
        ui->textEdit_target->setText(message);
    }
    return;
}

bool ToneAddItemDialog::parseToneResponse(const QJsonObject &root, QString &toneName, QString &tonePrompt, QString &targetText)
{
    toneName = root["tone_name"].toString();
    tonePrompt = root["tone_prompt"].toString();
    targetText = root["target_text"].toString();

    // 验证必要的字段
    return !toneName.isEmpty() && !targetText.isEmpty();
}

void ToneAddItemDialog::updateStep1NextButtonState()
{
    bool isEmpty = ui->lineEdit_tonestyle_name->text().isEmpty();
    ui->pushButton_confirm->setEnabled(!isEmpty);
}

void ToneAddItemDialog::on_toolButton_add_clicked()
{
    onSelectDocument();
    return;
}

void ToneAddItemDialog::initConnect()
{
    connect(ui->dropButton, &KBDropFileButton::sigSelectFile, this, &ToneAddItemDialog::onSelectDocument);
    connect(ui->dropButton, &KBDropFileButton::sigFileDropped, this, &ToneAddItemDialog::checkDuplicateName);
    //connect(ui->listview, &DocumentListView::sigFileDropped, this, &ToneAddItemDialog::checkDuplicateName);
    connect(mDelegate, &DocumentItemDelegate::sigDeleteBtnClicked, this, &ToneAddItemDialog::onShowDeleteConfirm);
    QPointer<ToneAddItemDialog> safeThis(this);
    connect(Globals::getinstance(), &Globals::fontsizeChanged, this, [safeThis](float fontSize) {
        if (!safeThis) return;  // 对象已销毁，直接返回

        QFont font;
        font.setPointSize(fontSize - 2);

        // 安全地操作成员
        QList<QWidget*> allWidgets = safeThis->findChildren<QWidget*>();
        for (QWidget* widget : allWidgets) {
            widget->setFont(font);
        }
        safeThis->setFont(font);
    });
    return;
}

void ToneAddItemDialog::checkEmptyState()
{
    if(mDocumentModel->getDocumentCount() == 0)
    {
        ui->stackedWidget_addFile->setCurrentWidget(ui->page_addFile);
    }
    else
    {
        ui->stackedWidget_addFile->setCurrentWidget(ui->page_list);
    }
    return;
}

void ToneAddItemDialog::onAddDocument(const QString &filePath)
{
    if (filePath.isEmpty() || !QFile::exists(filePath)) {
        qWarning() << "Invalid file path:" << filePath;
        return;
    }

    QFileInfo fileInfo(filePath);
    QString fileName = fileInfo.fileName();
    qint64 fileSize = fileInfo.size();

    // 检查是否已存在同名文件
    if (mDocumentModel->hasDocument(filePath)) {
        qWarning() << "Document already exists:" << filePath;
        return;
    }

    // 检查文件大小，超过5MB则拒绝添加
    if (fileSize > 5 * 1024 * 1024) {
        qWarning() << "File too large, cannot add:" << fileName << "Size:" << fileSize;
        return;
    }

    DocumentItem *item = new DocumentItem();
    item->documentName = fileName;
    item->documentPath = filePath;
    item->documentSize = fileSize;
    item->documentType = Globals::getFileIconName(filePath);

    mDocumentModel->addDocument(item);
    ui->listview->scrollToBottom();
    qDebug() << "add file:" << fileName << "path:" << filePath << mDocumentModel->getDocumentCount();

    checkEmptyState();
    ui->pushButton_parse->setEnabled(canEnableNextButton());
    return;
}

void ToneAddItemDialog::checkDuplicateName(const QStringList &filePaths)
{
    for (const QString &filePath : filePaths) {
        if (!mDocumentModel->hasDocument(filePath)) {
            onAddDocument(filePath);
        } else {
            qDebug() << "File already exists, skipping:" << filePath;
        }
    }
    return;
}

bool ToneAddItemDialog::onDeleteDocument(const QString &filePath)
{
    mDocumentModel->deleteDocument(filePath);
    checkEmptyState();
    ui->pushButton_parse->setEnabled(canEnableNextButton());

    return true;
}

bool ToneAddItemDialog::isTargetFile(const QString &documentPath)
{
    QFileInfo fileInfo(documentPath);
    if (!fileInfo.exists()) {
        return false;
    }

    QString suffix = fileInfo.suffix().toLower();
    return targetSuffixes.contains(suffix);
}

void ToneAddItemDialog::onShowDeleteConfirm(const QString &filePath)
{
    CustomMessageBox confirmMsg(this);
    confirmMsg.setWindowTitle(tr("kylin-aiassistant"));
    confirmMsg.setIcon(CustomMessageBox::Question);
    confirmMsg.setMessage(tr("Are you sure you want to delete this file?"));
    confirmMsg.setInformativeText(tr(""));
    confirmMsg.addButton(tr("Cancel"), CustomMessageBox::CancelButton);
    confirmMsg.addButton(tr("Delete"), CustomMessageBox::OkButton);
    confirmMsg.setButtons(CustomMessageBox::CancelButton | CustomMessageBox::OkButton);
    confirmMsg.setFixedHeight(172);

    int result = confirmMsg.exec();

    if (result == CustomMessageBox::OkButton)
    {
        onDeleteDocument(filePath);
    }

    return;
}

void ToneAddItemDialog::onSelectDocument()
{
    QStringList selectedFiles;
    QString fileName = FileDialogHelper::openWritingFile(0, this);
    if (!fileName.isEmpty()) {
        selectedFiles << fileName;
    }

    if(selectedFiles.isEmpty())
        return;

    checkDuplicateName(selectedFiles);
}

void ToneAddItemDialog::on_pushButton_cancel_clicked()
{
    this->close();
}

void ToneAddItemDialog::on_pushButton_parse_clicked()
{
    parsingTone();
    ui->stackedWidget_steps->setCurrentWidget(ui->page_parsing);
}

void ToneAddItemDialog::on_pushButton_prev_clicked()
{
    ui->stackedWidget_steps->setCurrentWidget(ui->page_fileList);
}

void ToneAddItemDialog::on_pushButton_confirm_clicked()
{
    this->close();
    ToneStyle info;
    info.toneName = ui->lineEdit_tonestyle_name->text();
    //info.toneInstruction = ui->textEdit_tonestyle_prompt->toPlainText();
    info.toneOriginal = ui->textEdit_original->toPlainText();
    info.toneTarget = ui->textEdit_target->toPlainText();
    QList<DocumentItem*> items = mDocumentModel->getDocumentList();
    DocumentItem* document = items.at(0);
    info.fileURL = document->documentPath;
    info.isCustom = true;

    Q_EMIT sigToneItemAdd(info);
}


void ToneAddItemDialog::on_toolButton_exampleText_clicked()
{
    // 先清空QTextEdit的内容
    ui->textEdit->clear();

    // 获取随机段落
    QString randomParagraph = m_paragraphManager->getNextParagraph();

    // 插入到QTextEdit中
    ui->textEdit->setPlainText(randomParagraph);
}


void ToneAddItemDialog::on_lineEdit_tonestyle_name_textChanged(const QString &arg1)
{
    updateStep1NextButtonState();
}

void ToneAddItemDialog::on_closeButton_clicked()
{
    this->close();
}

void ToneAddItemDialog::onParseTimeout()
{
    onRecParseError(QObject::tr("The task times out, please resend it."));
}

