#include "kasendbar.h"
#include "ctextedit.h"
#include "startuptools.h"
#include "msgpane.h"

#include <QEvent>
#include <QKeyEvent>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QScrollBar>
#include <QTime>
#include <QCoreApplication>

struct KASendBar::Private
{
    int max_show_rows;
    QString current_text = "";
    CTextEdit *sendEdit = nullptr;
    QPushButton *buttonClear = nullptr;
    QPushButton *buttonSend = nullptr;
};

KASendBar::KASendBar(QWidget *parent)
    : QWidget{parent},
      d_ptr(std::make_shared<KASendBar::Private>())
{
    d_ptr->max_show_rows = 5;
    initLayout();
    d_ptr->sendEdit->installEventFilter(this);
}

void KASendBar::setMaxShowRows(int rows)
{
    d_ptr->max_show_rows = rows;
}

void KASendBar::setEditEnabled(bool enable)
{
    d_ptr->sendEdit->setEnabled(enable);
    if (enable)
        d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    else
        d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //if (enable)
        // d_ptr->sendEdit->setFocus();
}

void KASendBar::setClearEnabled(bool enable)
{
    d_ptr->buttonClear->setEnabled(enable);
}

void KASendBar::onTextChange()
{
    QString text = d_ptr->sendEdit->toPlainText();

    if (text.isEmpty()) {
        d_ptr->buttonSend->setEnabled(false);
        d_ptr->buttonSend->setCheckable(false);
        d_ptr->buttonSend->setChecked(false);
        d_ptr->buttonSend->setAutoExclusive(false);
    } else {
        d_ptr->buttonSend->setEnabled(true);
        d_ptr->buttonSend->setCheckable(true);
        d_ptr->buttonSend->setChecked(true);
        d_ptr->buttonSend->setAutoExclusive(true);
        // d_ptr->buttonSend->setProperty("isImportant", true);
    }

    if (d_ptr->current_text != d_ptr->sendEdit->toPlainText())
        updateFixedHeight();
    d_ptr->current_text = d_ptr->sendEdit->toPlainText();
}

void KASendBar::updateFixedHeight()
{
    QTextDocument *text_doc = d_ptr->sendEdit->document();
    int font_height = QFontMetrics(d_ptr->sendEdit->font()).height();
    if (text_doc->size().height() < 36)
    {
        d_ptr->sendEdit->setFixedHeight(36);
        setFixedHeight(36);
        // d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        d_ptr->sendEdit->verticalScrollBar()->setVisible(false);
    }
    else if (text_doc->size().height() > font_height * d_ptr->max_show_rows + 8)
    {
        d_ptr->sendEdit->setFixedHeight(font_height * d_ptr->max_show_rows);
        setFixedHeight(font_height * d_ptr->max_show_rows + 8);
        // d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
        d_ptr->sendEdit->verticalScrollBar()->setVisible(true);
    }
    else
    {
        d_ptr->sendEdit->setFixedHeight(text_doc->size().height());
        setFixedHeight(text_doc->size().height());
        // d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        d_ptr->sendEdit->verticalScrollBar()->setVisible(false);
    }
}

void KASendBar::onButtonClearClicked()
{
    emit sigClearMessage();
    d_ptr->buttonClear->setEnabled(false);
}

void KASendBar::onButtonSendClicked()
{
    if (d_ptr->sendEdit->toPlainText().length() <= 0)
        return;

    bool flag = false;
    //识别是否为系统控制命令
    QString msg = d_ptr->sendEdit->toPlainText();

    //1、判断是否为dbus命令
    if (StartUpTools::getInstance()->inspectCtrl(msg)) {
        QTime dieTime = QTime::currentTime().addMSecs(800);
        while (QTime::currentTime() < dieTime) {
            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
        }
        qInfo() << "The wake word was matched successfully!";
        flag = true;
    }
    QString key = StartUpTools::getInstance()->findNmKey(msg);
    if (!key.isEmpty()) {
        QTime dieTime = QTime::currentTime().addMSecs(800);
        while (QTime::currentTime() < dieTime) {
            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
        }
        qInfo() << "The wake word was matched successfully!";
        StartUpTools::getInstance()->startUp(key);
        flag = true;
    }
    //2、判断打开还是关闭操作
    opType op = StartUpTools::getInstance()->isExit(msg);
    if (op != ORTHER){
        QString target = msg.mid(2);
        key = StartUpTools::getInstance()->findKey(target);

        //3、判断是否为可支持应用
        if (!key.isEmpty()) {
            QTime dieTime = QTime::currentTime().addMSecs(800);
            while (QTime::currentTime() < dieTime) {
                QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
            }
            qInfo() << "The wake word was matched successfully!";
            if (op == CLOSE) {
                StartUpTools::getInstance()->killProcess(key);
            } else if (op == OPEN){
                StartUpTools::getInstance()->startUp(key);
            }
            flag = true;
        }
    }

    emit sigSendMessage(msg);

    d_ptr->sendEdit->clear();
    d_ptr->buttonClear->setEnabled(false);
}

void KASendBar::initLayout()
{
    setFixedHeight(36);

    d_ptr->buttonClear = new QPushButton;
    connect(d_ptr->buttonClear, &QPushButton::clicked, this, &KASendBar::onButtonClearClicked);
    d_ptr->buttonClear->setFixedSize(36, 36);
    d_ptr->buttonClear->setIcon(QIcon(QString(":/icon/icon/clear.svg")));
    d_ptr->buttonClear->setToolTip(tr("Clear contextual connections"));
    d_ptr->buttonClear->setProperty("clearbtn", "true");
    d_ptr->buttonClear->setProperty("useIconHighlightEffect", 0x0);
    d_ptr->buttonClear->setProperty("isWindowButton", 0x1);
    d_ptr->buttonClear->setFocusPolicy(Qt::NoFocus);
    d_ptr->buttonClear->setFlat(true);
    d_ptr->buttonClear->setEnabled(false);

    QVBoxLayout *layout_left = new QVBoxLayout;
    layout_left->addStretch();
    layout_left->addWidget(d_ptr->buttonClear);

    d_ptr->sendEdit = new CTextEdit;
    d_ptr->sendEdit->setObjectName("sendEdit");
    connect(d_ptr->sendEdit, &QTextEdit::textChanged, this, &KASendBar::onTextChange);
    d_ptr->sendEdit->setFixedHeight(36);
//    d_ptr->sendEdit->setPlaceholderText(tr("Kylin AI assistance (win + space)"));Enter any of your questions
    d_ptr->sendEdit->setPlaceholderText(tr("Enter any of your questions..."));
    d_ptr->sendEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    d_ptr->sendEdit->verticalScrollBar()->setVisible(false);

    QVBoxLayout *layout_center = new QVBoxLayout;
    layout_center->addStretch();
    layout_center->addWidget(d_ptr->sendEdit);

    d_ptr->buttonSend = new QPushButton;
    connect(d_ptr->buttonSend, &QPushButton::clicked, this, &KASendBar::onButtonSendClicked);
    d_ptr->buttonSend->setFixedSize(36, 36);
    // d_ptr->buttonSend->setIcon(QIcon(QString(":/icon/icon/send-white.svg")));
    d_ptr->buttonSend->setProperty("sendbtn", "true");
    d_ptr->buttonSend->setFocusPolicy(Qt::NoFocus);
    d_ptr->buttonSend->setToolTip(tr("Send"));
    d_ptr->buttonSend->setFlat(true);
    d_ptr->buttonSend->setEnabled(false);

    QVBoxLayout *layout_right = new QVBoxLayout;
    layout_right->addStretch();
    layout_right->addWidget(d_ptr->buttonSend);

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addLayout(layout_left);
    // layout->addWidget(d_ptr->sendEdit);
    layout->addLayout(layout_center);
    layout->addLayout(layout_right);
}

bool KASendBar::eventFilter(QObject *watched, QEvent *event)
{
    if (watched->objectName() == "sendEdit" && event->type() == QEvent::KeyPress)
    {
        QKeyEvent* k_event = static_cast<QKeyEvent*>(event);
        if (k_event->modifiers() == Qt::NoModifier && (k_event->key() == Qt::Key_Enter || k_event->key() == Qt::Key_Return))
        {
            onButtonSendClicked();
            event->accept();
            return true;
        }
    }
    return QWidget::eventFilter(watched, event);
}

