/*
 * 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 "commandpage.h"
#include "systemchat.h"
#include "settingdialog.h"

#include <QMessageBox>

CommandPage::CommandPage(QWidget *parent)
    : QWidget{parent}
{
    initLayout();
    initConnection();
}


CommandPage::~CommandPage()
{

}


void CommandPage::initLayout()
{
    // 提示词模板
    m_titleLabel = new QLabel(this);
    m_titleLabel->setAccessibleName("kylin-aiassistant_QLabel_m_titleLabel");
    m_titleLabel->setText(tr("Prompt Template"));
    // 排序将同步影响“划词悬浮条”和“推荐提示词”下的模板位置
    m_tipLabel = new LightLabel(this);
    m_tipLabel->setAccessibleName("kylin-aiassistant_LightLabel_m_tipLabel");
    m_tipLabel->setFixedWidth(396);
    m_tipLabel->setText(tr("Sorting will synchronously affect the prompt words under the \"underline floating bar\" and \"recommended prompt words\""));
    QFont font;
    font.setPointSize(Globals::fontSize - 2);
    m_tipLabel->setFont(font);

    // 添加提示词
    m_addButton = new kdk::KBorderlessButton;
    m_addButton->setAccessibleName("kylin-aiassistant_kdk::KBorderlessButton_m_addButton");
    m_addButton->setIcon(QIcon::fromTheme("list-add-symbolic"));
    m_addButton->setIconSize(QSize(16, 16));
    m_addButton->setText(tr("Add"));
    m_addButton->setVisible(true);

    QHBoxLayout *titleHLayout = new QHBoxLayout;
    titleHLayout->setContentsMargins(16, 0, 16, 0);
    titleHLayout->addWidget(m_titleLabel);
    titleHLayout->addStretch();
    m_titleWidget = new QWidget(this);
    m_titleWidget->setAccessibleName("kylin-aiassistant_QWidget_m_titleWidget");
    m_titleWidget->setLayout(titleHLayout);

    QHBoxLayout *tipHLayout = new QHBoxLayout;
    tipHLayout->setContentsMargins(16, 0, 16, 0);
    tipHLayout->addWidget(m_tipLabel);
    tipHLayout->addStretch();
    tipHLayout->addWidget(m_addButton);
    m_tipWidget = new QWidget(this);
    m_tipWidget->setAccessibleName("kylin-aiassistant_QWidget_m_tipWidget");
    m_tipWidget->setLayout(tipHLayout);

    m_commandWidget = new QQuickWidget(this);
    m_commandWidget->setAccessibleName("kylin-aiassistant_QQuickWidget_m_commandWidget");
    m_commandWidget->setFixedWidth(496);

    m_commandWidget->rootContext()->setContextProperty("globals",Globals::getinstance());
    m_commandWidget->rootContext()->setContextProperty("commandTemplateListModel", CommandTemplateList::getInstance());
    m_commandWidget->rootContext()->setContextProperty("commandPage", this);
    m_commandWidget->setSource(QUrl("qrc:/qml/qml/PromptTemplateList.qml"));
    m_commandWidget->setVisible(true);
    m_commandWidget->setResizeMode(QQuickWidget::ResizeMode::SizeViewToRootObject);

    QVBoxLayout *scrollVLayout = new QVBoxLayout;
    scrollVLayout->setContentsMargins(16, 0, 16, 0);
    scrollVLayout->setSpacing(0);
    scrollVLayout->addWidget(m_titleWidget);
    scrollVLayout->addWidget(m_tipWidget);
    scrollVLayout->addSpacing(8);
    scrollVLayout->addWidget(m_commandWidget);
    scrollVLayout->addStretch();
    m_scrollWidget = new QWidget(this);
    m_scrollWidget->setAccessibleName("kylin-aiassistant_QWidget_m_scrollWidget");
    m_scrollWidget->setLayout(scrollVLayout);

    m_scrollArea = new QScrollArea(this);
    m_scrollArea->setAccessibleName("kylin-aiassistant_QScrollArea_m_scrollAreat");
    m_scrollArea->setFixedSize(528, 404);
    m_scrollArea->setWidgetResizable(true);
    m_scrollArea->setFocusPolicy(Qt::NoFocus);
    m_scrollArea->setFrameShape(QFrame::NoFrame); // 滑动区无边框
    m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_scrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
    m_scrollArea->setWidget(m_scrollWidget);

    QVBoxLayout *baseVLayout = new QVBoxLayout;
    baseVLayout->setContentsMargins(0, 0, 0, 0);
    baseVLayout->setSpacing(0);
    baseVLayout->addWidget(m_scrollArea);
    baseVLayout->addStretch();

    m_scrollWidget->setObjectName("commandPageWidget");

    setLayout(baseVLayout);
}

void CommandPage::initConnection()
{
    connect(m_addButton, &QPushButton::clicked, this, &CommandPage::onAddBtnClicked);
    connect(CommandTemplateList::originalCommandListModel, &CommandTemplateList::sigCreateCommand, this, &CommandPage::onCreateCommand);
    connect(CommandTemplateList::originalCommandListModel, &CommandTemplateList::sigUpdateCommand, this, &CommandPage::onEditCommand);
    connect(Globals::getinstance(), &Globals::fontsizeChanged, [&](float fontSize){
        QFont font;
        font.setPointSize(fontSize - 2);
        m_tipLabel->setFont(font);
    });
}

void CommandPage::onAddBtnClicked()
{
    CommandConfigDialog dia(SettingDialog::sharedInstance);
    int widgetWidth = SettingDialog::sharedInstance->width();
    int widgetHeight = SettingDialog::sharedInstance->height();
    int x = (widgetWidth - dia.width()) / 2 + SettingDialog::sharedInstance->x();
    int y = (widgetHeight - dia.height()) / 2 + SettingDialog::sharedInstance->y();
    KyInfo() << "onAddBtnClicked" << x << y << widgetWidth << "-----" << widgetHeight << "-----"
             <<  dia.width() << "-----" << dia.height() << "-----"
             << SettingDialog::sharedInstance->x() << "-----" << SettingDialog::sharedInstance->y();
    dia.move(x, y);
    dia.exec();
//    KyInfo() << "添加结束";

}

void CommandPage::onCommandClicked(int type, int actorId, QString name, QString content)
{
    PromptContentAccessType commandType = static_cast<PromptContentAccessType>(type);
    CommandConfigDialog dia(commandType, actorId, name, content, SettingDialog::sharedInstance);
    int widgetWidth = SettingDialog::sharedInstance->width();
    int widgetHeight = SettingDialog::sharedInstance->height();
    int x = (widgetWidth - dia.width()) / 2 + SettingDialog::sharedInstance->x();
    int y = (widgetHeight - dia.height()) / 2 + SettingDialog::sharedInstance->y();
    KyInfo() << "onCommandClicked" << x << y << widgetWidth << "-----" << widgetHeight << "-----"
             <<  dia.width() << "-----" << dia.height() << "-----"
             << SettingDialog::sharedInstance->x() << "-----" << SettingDialog::sharedInstance->y();
    dia.move(x, y);
    dia.exec();
//    KyInfo() << "编辑结束";

}

void CommandPage::onCreateCommand(QString name, QString content)
{
    SystemChat *systemChat = SystemChat::getPtr();
    int id = systemChat->createCommand(name, content);

    if (id == -1) {
        showErrorMessage(QString(tr("Failed to create prompt word, prompt word name: %1.").arg(name)), SettingDialog::sharedInstance);
        KyInfo() << "提示词创建失败" << id << name << content;
    } else {
        CommandTemplateList::originalCommandListModel->addData(PromptContentAccessType::ReadWrite, id, name, content);
        KyInfo() << "提示词创建成功" << id << name << content;
    }

}

void CommandPage::onEditCommand(int actorId, QString name, QString content)
{
    SystemChat *systemChat = SystemChat::getPtr();
    bool ret = systemChat->updateCommand(actorId, name, content);
    if (ret == false) {
        showErrorMessage(QString(tr("Failed to edit prompt word, prompt word name: %1.").arg(name)), SettingDialog::sharedInstance);
        KyInfo() << "提示词编辑失败";
    } else {
        CommandTemplateList::originalCommandListModel->updateData(actorId, name, content);
    }
}

void CommandPage::showConfirmMessage(int actorId, QString name)
{
    QMessageBox msgBox(SettingDialog::sharedInstance);
    msgBox.setWindowTitle(tr("kylin-aiassistant"));
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText(tr("After deleting the prompt word template, it cannot be restored. Are you sure you want to delete it?"));

    QPushButton *cancelButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
    QPushButton *sureButton = msgBox.addButton(tr("Delete"), QMessageBox::AcceptRole);
    msgBox.setDefaultButton(sureButton);
    msgBox.exec();

    if ((QPushButton *)msgBox.clickedButton() == sureButton) {
        // 删除提示词
        SystemChat *systemChat = SystemChat::getPtr();
        bool deleteSuccess = systemChat->deleteCommand(actorId);

        if (!deleteSuccess) {
            // 删除失败
            showErrorMessage(QString(tr("Failed to delete prompt word, prompt word name: %1.").arg(name)), SettingDialog::sharedInstance);
            KyInfo() << "Failed to delete command with actorId: " << actorId << " and name: " << name;

        } else {
            // 删除成功
            CommandTemplateList::originalCommandListModel->removeData(actorId, name);
            CommandTemplateList::originalCommandListModel->deleteCommand(actorId, name);
            CommandTemplateList::originalCommandListModel->resetAllData();
            KyInfo() << "Successfully deleted command with actorId: " << actorId << " and name: " << name;
        }

    } else {

    }
}

void CommandPage::showErrorMessage(const QString &message, QWidget *parent)
{
    QMessageBox msgBox(parent);
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(message);

    QPushButton *cancelButton = msgBox.addButton(tr("Cancel"), QMessageBox::RejectRole);
    QPushButton *sureButton = msgBox.addButton(tr("Ok"), QMessageBox::AcceptRole);
    msgBox.setDefaultButton(sureButton);
    msgBox.exec();
}

void CommandPage::onContentHeightChanged(int height)
{
     m_commandWidget->setFixedHeight(height);
}
