/*
 * Copyright (C) 2020, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include "commandconfigdialog.h"
#include "settingdialog.h"

#include <QLineEdit>
#include <QScrollBar>
#include <QTextEdit>
#include <QTextCursor>
#include <QTextCharFormat>
#include <QColor>
#include <QDebug>

#include <ukuistylehelper/ukuistylehelper.h>
#include <ukuiwindowhelper/ukuiwindowhelper.h>

#define MAX_NAME_COUNT 16
#define MAX_CONTENT_COUNT 2000

class CommandConfigDialog::Private
{
public:

    CommandTemplateItem item;
    PromptContentAccessType m_commandType;
    QString m_name = "";
    QString m_content = "";
    int m_actorId;
    bool isEdit = false;

    QLabel *m_titleLabel = nullptr;
    QLabel *m_nameLabel = nullptr;
    QLabel *m_contentLabel = nullptr;
    QLabel *m_asteriskLabel1 = nullptr;
    QLabel *m_asteriskLabel2 = nullptr;
    QLabel *m_tipLabel1 = nullptr;
    QLabel *m_tipLabel2 = nullptr;

    QLineEdit *m_nameLineEdit = nullptr;
    QTextEdit *m_contentTextEdit = nullptr;

    QPushButton *m_titleIcon = nullptr;
    QPushButton *m_closeBtn = nullptr;
    QPushButton *m_promptIcon = nullptr;
    QPushButton *m_cancelBtn = nullptr;
    QPushButton *m_acceptBtn = nullptr;

    QVBoxLayout *m_vLayout = nullptr;
};

CommandConfigDialog::CommandConfigDialog(QWidget *parent):
    QDialog{parent},
    d_ptr(make_shared<Private>())
{
    d_ptr->isEdit = false;
    d_ptr->m_commandType = PromptContentAccessType::ReadWrite;
    initLayout();
    initConnect();
    changeTheme();
    d_ptr->m_titleLabel->setText(tr("Add Template"));
    d_ptr->m_acceptBtn->setText(tr("Add"));
}

CommandConfigDialog::CommandConfigDialog(PromptContentAccessType commandType, int actorId, QString name, QString content, QWidget *parent):
    QDialog{parent},
    d_ptr(make_shared<Private>())
{
    d_ptr->isEdit = true;
    d_ptr->m_name = name;
    d_ptr->m_content = content;
    initLayout();
    initConnect();
    changeTheme();
    if (commandType == PromptContentAccessType::ReadWrite) {
        d_ptr->m_titleLabel->setText(tr("Edit Template"));
        d_ptr->m_cancelBtn->setVisible(true);
        d_ptr->m_acceptBtn->setEnabled(false);
    } else {
        d_ptr->m_titleLabel->setText(tr("View Template"));
        d_ptr->m_cancelBtn->setVisible(false);
        d_ptr->m_acceptBtn->setEnabled(true);
    }

    d_ptr->m_acceptBtn->setText(tr("Accept"));
    loadData(commandType, actorId, name, content);
}

CommandConfigDialog::~CommandConfigDialog()
{

}

void CommandConfigDialog::initLayout()
{
    setFixedSize(420, 436);
#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper *ukuiWindowHelper = new UkuiWindowHelper(this);
    ukuiWindowHelper->removeTitleBar();
#else
    kdk::UkuiStyleHelper::self()->removeHeader(this);
#endif
    this->setFocusPolicy(Qt::ClickFocus);
    this->setFocus();

    d_ptr->m_titleIcon = new QPushButton;
    d_ptr->m_titleIcon->setAccessibleName("kylin-aiassistant_QPushButton_d_ptr->m_titleIcon");
    d_ptr->m_titleIcon->setFlat(true);
    d_ptr->m_titleIcon->setIconSize(QSize(24, 24));
    d_ptr->m_titleIcon->setFixedSize(24, 24);
    d_ptr->m_titleIcon->setAttribute(Qt::WA_TransparentForMouseEvents,true);
//    d_ptr->m_titleIcon->setIcon(QIcon::fromTheme("kylin-ai-assistant"));
    d_ptr->m_titleIcon->setIcon(QIcon(":/icon/icon/AI-Writing.svg"));
    d_ptr->m_titleLabel = new QLabel;
    d_ptr->m_titleLabel->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_titleLabel");
    d_ptr->m_titleLabel->setFixedHeight(20);

    d_ptr->m_closeBtn = new QPushButton;
    d_ptr->m_closeBtn->setAccessibleName("kylin-aiassistant_QPushButton_d_ptr->m_closeBtn");
    d_ptr->m_closeBtn->setFlat(true);
    d_ptr->m_closeBtn->setFixedSize(32, 32);
    d_ptr->m_closeBtn->setProperty("isWindowButton", 0x2);
    d_ptr->m_closeBtn->setProperty("useIconHighlightEffect", 0x8);
    d_ptr->m_closeBtn->setIcon(QIcon::fromTheme("window-close-symbolic"));
    d_ptr->m_closeBtn->setToolTip(tr("Close"));

    QWidget *titleWidget = new QWidget();
    titleWidget->setAccessibleName("kylin-aiassistant_QWidget_titleWidget");
    titleWidget->setFixedSize(420, 40);
    QHBoxLayout *titleHLayout = new QHBoxLayout(titleWidget);
    titleHLayout->setContentsMargins(8, 0, 4, 0);
    titleHLayout->addWidget(d_ptr->m_titleIcon);
    titleHLayout->addWidget(d_ptr->m_titleLabel);
    titleHLayout->addStretch();
    titleHLayout->addWidget(d_ptr->m_closeBtn);

    d_ptr->m_nameLabel = new QLabel(tr("Prompt Name"));
    d_ptr->m_nameLabel->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_nameLabel");
    d_ptr->m_contentLabel = new QLabel(tr("Prompt Content"));
    d_ptr->m_contentLabel->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_contentLabel");
    d_ptr->m_asteriskLabel1 = new QLabel("*");
    d_ptr->m_asteriskLabel1->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_asteriskLabel1");
    d_ptr->m_asteriskLabel1->setStyleSheet("QLabel { color: red; }");
    d_ptr->m_asteriskLabel2 = new QLabel("*");
    d_ptr->m_asteriskLabel2->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_asteriskLabel2");
    d_ptr->m_asteriskLabel2->setStyleSheet("QLabel { color: red; }");

    QWidget *nameHWidget = new QWidget;
    nameHWidget->setAccessibleName("kylin-aiassistant_QWidget_nameHWidget");
    QHBoxLayout *nameHLayout = new QHBoxLayout;
    nameHLayout->setContentsMargins(0, 0, 0, 0);
    nameHLayout->addWidget(d_ptr->m_nameLabel);
    nameHLayout->addWidget(d_ptr->m_asteriskLabel1);
    nameHLayout->setAlignment(Qt::AlignLeft);
    nameHLayout->setSpacing(0);
    nameHWidget->setLayout(nameHLayout);

    QWidget *contentHWidget = new QWidget;
    contentHWidget->setAccessibleName("kylin-aiassistant_QWidget_contentHWidget");
    QHBoxLayout *contentHLayout = new QHBoxLayout;
    contentHLayout->setContentsMargins(0, 0, 0, 0);
    contentHLayout->addWidget(d_ptr->m_contentLabel);
    contentHLayout->addWidget(d_ptr->m_asteriskLabel2);
    contentHLayout->setAlignment(Qt::AlignLeft);
    contentHLayout->setSpacing(0);
    contentHWidget->setLayout(contentHLayout);

    d_ptr->m_promptIcon = new QPushButton;
    d_ptr->m_promptIcon->setAccessibleName("kylin-aiassistant_QPushButton_d_ptr->m_promptIcon");
    d_ptr->m_promptIcon->setIconSize(QSize(16, 16));
    d_ptr->m_promptIcon->setFixedSize(36, 36);
    d_ptr->m_promptIcon->setAttribute(Qt::WA_TransparentForMouseEvents,true);
    d_ptr->m_promptIcon->setIcon(QIcon(":/icon/icon/setting/prompt.svg"));
    d_ptr->m_promptIcon->setEnabled(false);

    d_ptr->m_nameLineEdit = new QLineEdit;
    d_ptr->m_nameLineEdit->setAccessibleName("kylin-aiassistant_QLineEdit_d_ptr->m_nameLineEdit");
    d_ptr->m_nameLineEdit->setFixedHeight(36);
    d_ptr->m_nameLineEdit->setPlaceholderText(tr("Enter prompt word title, for example: Smart Reply"));
    d_ptr->m_nameLineEdit->clearFocus();

    QWidget *nameEditHWidget = new QWidget;
    nameEditHWidget->setAccessibleName("kylin-aiassistant_QWidget_nameEditHWidget");
    QHBoxLayout *nameEditHLayout = new QHBoxLayout;
    nameEditHLayout->setContentsMargins(0, 8, 0, 0);
    nameEditHLayout->setAlignment(Qt::AlignLeft);
    nameEditHLayout->setSpacing(0);
    nameEditHLayout->addWidget(d_ptr->m_promptIcon);
    nameEditHLayout->addSpacing(8);
    nameEditHLayout->addWidget(d_ptr->m_nameLineEdit);
    nameEditHWidget->setLayout(nameEditHLayout);

    d_ptr->m_tipLabel1 = new QLabel(tr("The length must not exceed 16 characters"));
    d_ptr->m_tipLabel1->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_tipLabel1");
    d_ptr->m_tipLabel1->setContentsMargins(44, 0, 0, 0);
    d_ptr->m_tipLabel1->setStyleSheet("color:rgba(245, 63, 63, 1);");
    d_ptr->m_tipLabel1->setVisible(false);

    QWidget *nameEditVWidget = new QWidget;
    nameEditVWidget->setAccessibleName("kylin-aiassistant_QWidget_nameEditVWidget");
    nameEditVWidget->setFixedHeight(68);
    QVBoxLayout *nameEditVLayout = new QVBoxLayout;
    nameEditVLayout->setContentsMargins(0, 0, 0, 0);
    nameEditVLayout->addWidget(nameEditHWidget);
    nameEditVLayout->addWidget(d_ptr->m_tipLabel1);
    nameEditVLayout->setAlignment(Qt::AlignTop);
    nameEditVLayout->setSpacing(0);
    nameEditVWidget->setLayout(nameEditVLayout);

    d_ptr->m_contentTextEdit = new QTextEdit;
    d_ptr->m_contentTextEdit->setAccessibleName("kylin-aiassistant_QTextEdit_d_ptr->m_contentTextEdit");
    d_ptr->m_contentTextEdit->setFixedHeight(172);
    d_ptr->m_contentTextEdit->setPlaceholderText(tr("Enter the prompt word content, for example:\n"
                                                    "You are an intelligent chat assistant with the goal of automatically replying to messages from friends."
                                                    "Imitate the user's communication style with concise and natural language."
                                                    "I will send you a message from the other party, and you need to judge the context based on the message content,"
                                                    "reply to the message in a timely manner, provide practical advice or friendly responses."
                                                    "If you are unsure of the answer, you can politely explain to avoid misleading the user."
                                                    "Ensure language is friendly, appropriate, and suitable for daily communication."));
    d_ptr->m_contentTextEdit->setStyleSheet("QTextEdit {"
                                            "border: 2px;"
                                            "border-radius: 4px;"
                                            "border-color: rgba(38, 38, 38, 0.05);"
                                            "background-color: rgba(38, 38, 38, 0.05);"
                                            "}"
                                            "QTextEdit:focus {"
                                            "border: 2px solid rgba(38, 38, 38, 0.05);"
                                            "border-radius: 4px;"
                                            "border-color: rgba(55, 144, 250, 1);"
                                            "background-color: rgba(255, 255, 255, 1);"
                                            "}");
    d_ptr->m_contentTextEdit->verticalScrollBar()->setProperty("drawScrollBarGroove", false); // 隐藏滚动条滑槽
    d_ptr->m_contentTextEdit->setAcceptRichText(false); // 仅接受纯文本输入
    d_ptr->m_contentTextEdit->clearFocus();

    d_ptr->m_tipLabel2 = new QLabel(tr("The length must not exceed 2000 characters"));
    d_ptr->m_tipLabel2->setAccessibleName("kylin-aiassistant_QLabel_d_ptr->m_tipLabel2");
    d_ptr->m_tipLabel2->setStyleSheet("color:rgba(245, 63, 63, 1);");
    d_ptr->m_tipLabel2->setVisible(false);

    QWidget *contentVWidget = new QWidget;
    contentVWidget->setAccessibleName("kylin-aiassistant_QWidget_contentVWidget");
    QVBoxLayout *contentVLayout = new QVBoxLayout;
    contentVLayout->setContentsMargins(0, 8, 0, 0);
    contentVLayout->addWidget(d_ptr->m_contentTextEdit);
    contentVLayout->addWidget(d_ptr->m_tipLabel2);
    contentVLayout->setAlignment(Qt::AlignTop);
    contentVLayout->setSpacing(0);
    contentVWidget->setLayout(contentVLayout);

    d_ptr->m_cancelBtn = new QPushButton(tr("Cancel"));
    d_ptr->m_cancelBtn->setAccessibleName("kylin-aiassistant_QPushButton_d_ptr->m_cancelBtn");
    d_ptr->m_cancelBtn->setFixedSize(80, 36);
    d_ptr->m_cancelBtn->setFocusPolicy(Qt::NoFocus);
    d_ptr->m_cancelBtn->setProperty("useButtonPalette", true);

    d_ptr->m_acceptBtn = new QPushButton(tr("Accept"));
    d_ptr->m_acceptBtn->setAccessibleName("kylin-aiassistant_QPushButton_d_ptr->m_acceptBtn");
    d_ptr->m_acceptBtn->setFixedSize(80, 36);
    d_ptr->m_acceptBtn->setFocusPolicy(Qt::NoFocus);
    d_ptr->m_acceptBtn->setEnabled(false);

    QHBoxLayout *buttonLayout = new QHBoxLayout;
    buttonLayout->setContentsMargins(0, 0, 0, 0);
    buttonLayout->addStretch();
    buttonLayout->addWidget(d_ptr->m_cancelBtn);
    buttonLayout->setSpacing(8);
    buttonLayout->addWidget(d_ptr->m_acceptBtn);

    QVBoxLayout *contentLayout = new QVBoxLayout;
    contentLayout->setSpacing(0);
    contentLayout->setContentsMargins(24, 16, 24, 24);
    contentLayout->addWidget(nameHWidget);
    contentLayout->addWidget(nameEditVWidget);
    contentLayout->addWidget(contentHWidget);
    contentLayout->addWidget(contentVWidget);
    contentLayout->addStretch();
    contentLayout->addLayout(buttonLayout);

    QWidget *contentWidget = new QWidget;
    contentWidget->setAccessibleName("kylin-aiassistant_QWidget_contentWidget");
    contentWidget->setContentsMargins(0, 0, 0, 0);
    contentWidget->setLayout(contentLayout);

    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->setContentsMargins(0, 0, 0, 0);
    vLayout->setSpacing(0);
    vLayout->addWidget(titleWidget);
    vLayout->addWidget(contentWidget);
    this->setLayout(vLayout);
}

void CommandConfigDialog::initConnect()
{
    connect(SettingDialog::sharedInstance, &SettingDialog::sigChangeTheme, this, &CommandConfigDialog::changeTheme);

    // 指令名称 字数限制16
    connect(d_ptr->m_nameLineEdit, &QLineEdit::textChanged, this, [=](const QString &text) {

        int totalUnits = 0;
        QString truncatedText;
        for (int i = 0; i < text.length(); ++i) {
            QChar currentChar = text[i];
            // 中文、英文或其他字符占用 1 个单位
            totalUnits += 1;
            // 如果超出最大长度，就截取到此为止
            if (totalUnits > MAX_NAME_COUNT) {
                break;
            }

            truncatedText.append(currentChar);
        }

        if (text != truncatedText) {
            d_ptr->m_tipLabel1->setVisible(true);
            d_ptr->m_nameLineEdit->setText(truncatedText);
        }

        if (totalUnits < MAX_NAME_COUNT) {
            d_ptr->m_tipLabel1->setVisible(false);
        }

        updateButtonState();

    });

    // 指令内容 字数限制2000
    connect(d_ptr->m_contentTextEdit, &QTextEdit::textChanged, this, [=]() {

        QString text = d_ptr->m_contentTextEdit->toPlainText();
        int totalUnits = 0;
        QString truncatedText;
        for (int i = 0; i < text.length(); ++i) {
            QChar currentChar = text[i];
            // 中文、英文或其他字符占用 1 个单位
            totalUnits += 1;
            // 如果超出最大长度，就截取到此为止
            if (totalUnits > MAX_CONTENT_COUNT) {
                break;
            }

            truncatedText.append(currentChar);
        }

        if (text != truncatedText) {
            d_ptr->m_tipLabel2->setVisible(true);
            d_ptr->m_contentTextEdit->setText(truncatedText);
            // 重新设置光标位置到末尾
            QTextCursor cursor = d_ptr->m_contentTextEdit->textCursor();
            cursor.movePosition(QTextCursor::End);
            d_ptr->m_contentTextEdit->setTextCursor(cursor);
        }

        if (totalUnits < MAX_CONTENT_COUNT) {
            d_ptr->m_tipLabel2->setVisible(false);
        }

        updateButtonState();

    });

    connect(d_ptr->m_closeBtn, &QPushButton::clicked, [this](){reject();});
    connect(d_ptr->m_cancelBtn, &QPushButton::clicked, [this](){reject();});
    connect(d_ptr->m_acceptBtn, &QPushButton::clicked, [this](){accept();});

}

void CommandConfigDialog::changeTheme()
{
    KyInfo() << "changetheme";
    QPalette p = this->palette();
    QColor color = p.color(QPalette::Base);
    p.setColor(QPalette::Window, color);
    this->setPalette(p);
}

void CommandConfigDialog::updateButtonState()
{
    if (d_ptr->m_nameLineEdit->text().length() > 0 && d_ptr->m_contentTextEdit->toPlainText().length()> 0) {

        if (d_ptr->isEdit == true && d_ptr->m_commandType == PromptContentAccessType::ReadWrite) {
            // 编辑自定义提示词弹窗，两个输入框都有内容
            if (d_ptr->m_name == d_ptr->m_nameLineEdit->text() && d_ptr->m_content == d_ptr->m_contentTextEdit->toPlainText()) {
                // 无内容修改
                KyInfo() << "No content modification";
                d_ptr->m_acceptBtn->setEnabled(false);
            } else {
                // 有内容修改
                KyInfo() << "The content has been modified";
                d_ptr->m_acceptBtn->setEnabled(true);
                d_ptr->m_acceptBtn->setProperty("isImportant", true);
            }

        } else {
            // 添加弹窗或者查看预设提示词弹窗，两个输入框都有内容
            d_ptr->m_acceptBtn->setEnabled(true);
            d_ptr->m_acceptBtn->setProperty("isImportant", true);
        }

    } else {
        // 至少一个输入框内容为空
        d_ptr->m_acceptBtn->setEnabled(false);
    }

}

void CommandConfigDialog::accept()
{
    QString name = d_ptr->m_nameLineEdit->text();
    QString content = d_ptr->m_contentTextEdit->toPlainText();

    if (d_ptr->isEdit == false) {
        CommandTemplateList::originalCommandListModel->createCommand(name, content);

    } else {
        if (d_ptr->m_commandType == PromptContentAccessType::ReadWrite) {
            CommandTemplateList::originalCommandListModel->updateCommand(d_ptr->m_actorId, name, content);
        }
    }

    return QDialog::accept();
}

void CommandConfigDialog::loadData(PromptContentAccessType commandType, int actorId, QString name, QString content)
{
    d_ptr->m_commandType = commandType;
    d_ptr->m_actorId = actorId;

    QMap<int, QString> iconMap = {
        {1, ":/icon/icon/setting/text-expend.svg"},
        {2, ":/icon/icon/setting/text-polish.svg"},
        {3, ":/icon/icon/setting/translate.svg"},
        {5, ":/icon/icon/setting/todo-generate.svg"},
        {6, ":/icon/icon/setting/weekly-report.svg"},
        {7, ":/icon/icon/setting/new-schedule.svg"},
        {8, ":/icon/icon/setting/text-proofread.svg"},
        {9, ":/icon/icon/setting/summary.svg"}
    };

    // 设置图标
    if (iconMap.contains(actorId)) {
        d_ptr->m_promptIcon->setIcon(QIcon(iconMap[actorId]));
    } else {
        d_ptr->m_promptIcon->setIcon(QIcon(":/icon/icon/setting/prompt.svg")); // 设置默认图标
    }

    if (commandType == PromptContentAccessType::ReadOnly) {
        // 禁止编辑
        d_ptr->m_nameLineEdit->setText(name);
        d_ptr->m_nameLineEdit->setReadOnly(true);
        d_ptr->m_nameLineEdit->setStyleSheet("QLineEdit { color: rgba(0, 0, 0, 0.35); }");

//        d_ptr->m_contentTextEdit->setText(content);
        d_ptr->m_contentTextEdit->setReadOnly(true);
        QTextCharFormat format;
        format.setForeground(QColor(0, 0, 0, 89)); // rgba(0, 0, 0, 0.35) 0.35 * 255 ≈ 89

        QTextCursor cursor = d_ptr->m_contentTextEdit->textCursor();
        cursor.mergeCharFormat(format);
        cursor.insertText(content);
        d_ptr->m_contentTextEdit->setTextCursor(cursor); // 把光标返回到 QTextEdit 中


    } else if (commandType == PromptContentAccessType::ReadWrite) {
        // 允许编辑
        d_ptr->m_nameLineEdit->setText(name);
        d_ptr->m_contentTextEdit->setText(content);

    } else {
        KyInfo() << "No permission to view";
    }

    d_ptr->m_contentTextEdit->moveCursor(QTextCursor::Start);


}

void CommandConfigDialog::keyPressEvent(QKeyEvent *event)
{
    // Key_Enter是小键盘的确认键，Key_Return是大键盘的回车键
    if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {

        // 自定义指令
        if (d_ptr->m_commandType == PromptContentAccessType::ReadWrite) {
            // 焦点在第一个输入框，不执行任何操作
            if (d_ptr->m_nameLineEdit->hasFocus()) {
                return;
            }
            // 焦点在第二个输入框，执行换行操作
            if (d_ptr->m_contentTextEdit->hasFocus()) {
                d_ptr->m_contentTextEdit->insertPlainText("\n");
                return;
            }
            // 焦点不在输入框里，并且两个输入框都有内容，执行确认操作
            KyInfo() << "d_ptr->m_nameLineEdit->text().isEmpty()" <<d_ptr->m_nameLineEdit->text().isEmpty() << "d_ptr->m_contentTextEdit->toPlainText().isEmpty()" << d_ptr->m_contentTextEdit->toPlainText().isEmpty()
                     << "d_ptr->m_acceptBtn->isEnabled()" <<d_ptr->m_acceptBtn->isEnabled();
            if (!d_ptr->m_nameLineEdit->text().isEmpty() && !d_ptr->m_contentTextEdit->toPlainText().isEmpty() &&
                d_ptr->m_acceptBtn->isEnabled()) {

                emit accept();  // 执行确认操作
            }

        } else {
            // 预设指令，直接执行确认操作
            if (d_ptr->m_acceptBtn->isEnabled()) {
                emit accept();
            }
        }
    }
}
