/*
 * 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 "selection.h"
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDialog>
#include <QLabel>
#include <QMouseEvent>
#include <QStyle>
#include <QStyleOption>
#include <QPainter>
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnection>
#include <QDebug>
#include <QMenu>
#include <QTimer>
#include <QQmlContext>
#include <QGuiApplication>
#include <QScreen>
#include <QtGlobal>
#include "mypushbutton.h"
#include <windowmanager/windowmanager.h>
#include <kysdk/kysdk-system/libkydatacollect.h>
#include <ukuistylehelper/ukuistylehelper.h>


SelectWidget::SelectWidget(QWidget *parent)
{
    this->setWindowFlags(Qt::WindowStaysOnTopHint);
    //初始化划词主界面
    initQmlSelectWidget();
    this->setContentsMargins(0,0,0,0);
    //初始化更多指令界面
    initSelectMoreCommandWidget();
    //初始化划词动画
    initAnimation();
    //初始化划词菜单
    initMenu();
    //添加事件过滤器
    installEventFilter(this);

#ifdef UKUI_WINDOWHELPER_SUPPORT
    m_ukuiWindowHelper = new UkuiWindowHelper(this);
#endif
}

void SelectWidget::initQmlSelectWidget()
{

    m_quickWidget = new QQuickWidget(this);
    m_quickWidget->setAccessibleName("kylin-aiassistant_QQuickWidget_m_quickWidget");
    m_quickWidget->setContentsMargins(0,0,0,0);
    //添加指令模型
    m_quickWidget->rootContext()->setContextProperty("commandTemplateListModel", CommandTemplateList::originalCommandListModel);
    m_quickWidget->setSource(QUrl("qrc:/qml/qml/Select.qml"));

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper *ukuiWindowHelper = new UkuiWindowHelper(this);
    ukuiWindowHelper->removeTitleBar();
    ukuiWindowHelper->setSkipTaskBar(true);
#else
    kdk::UkuiStyleHelper::self()->removeHeader(this);
    kdk::WindowManager::setSkipTaskBar(this->windowHandle(), true);
#endif
    //链接发送命令信号
    //在quickwidget中的qml发送一个带参数的信号槽到quickwidget所在的cpp中，然后建立信号槽的链接
    QQuickItem *item=m_quickWidget->rootObject();
    if(item){
            QObject::connect(item, SIGNAL(sigSendButtonText(QString, int)),this, SLOT(sendButtonText(QString, int)));
            QObject::connect(item, SIGNAL(sigResizeRect(bool,int,int,int)),this,SLOT(slResizeRect(bool,int,int,int)));
            QObject::connect(item,SIGNAL(sigsettingButtonLeftClicked()),this,SLOT(slShowContextMenu()));
            QObject::connect(item,SIGNAL(sigShowToolTip(bool)),this,SLOT(slShowToolTip(bool)));
            QObject::connect(this, &SelectWidget::sigDisableMorePage,item,[=]{
                  //执行隐藏更多界面功能
                  QMetaObject::invokeMethod(item, "onsigDisableMorePage");
            });
    }


}
void SelectWidget::sendButtonText(const QString &currentButtonText,const int currentId)
{
    KyInfo() << "aaaaaaaaaaaaaaaaaaaaaaaa当前指令为:" << currentButtonText <<"当前ID为"<< currentId;
    //填充当前按钮文本
    if(!currentButtonText.isEmpty())
    {
        KyInfo() << "currentButtonText" << currentButtonText;
        buttonText = currentButtonText;
        m_selectMoreCommandWidget->setVisible(false);
        emit sigDisableMorePage();
    }
    if(currentId != -1)
    {
        KyInfo() << "currentId" << currentId;
        promptId = currentId;
    }
    emit sigbuttontext();
}

void SelectWidget::slResizeRect(bool isMoreButtonPressed, const int width, const int height, const int moreCommandStartPos)
{
   m_quickWidget->setFixedSize(width+20,height+50);
   this->setFixedSize(width, height);
   m_moreCommandStartPos = moreCommandStartPos;
   if(m_selectMoreCommandWidget && isMoreButtonPressed)
   {
       m_selectMoreCommandWidget->setVisible(true);
       m_selectMoreCommandWidget->move(this->x()+moreCommandStartPos,this->y()+this->height()+6);
   }
   else{
       m_selectMoreCommandWidget->setVisible(false);

   }
}

void SelectWidget::initSelectMoreCommandWidget()
{
    m_selectMoreCommandWidget = new SelectMoreCommandWidget(this );
    m_selectMoreCommandWidget->setAccessibleName("kylin-aiassistant_SelectMoreCommandWidget_m_selectMoreCommandWidget");
    m_selectMoreCommandWidget->setVisible(false);
    connect(m_selectMoreCommandWidget,&SelectMoreCommandWidget::sigCurrentCommandText,this,&SelectWidget::sendButtonText);
}

void SelectWidget::slShowToolTip(bool isShow)
{
    QPoint cursorPos = QCursor::pos();

    if(isShow)
    {
        QToolTip::showText(cursorPos,tr("Send to AI Assistant"),this);

    }
    else
    {
        QToolTip::showText(cursorPos,"",this);

    }
}


void SelectWidget::slSettingButtonClicked()
{
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "send_scribe_words_content_button_click_event", "scribeWordsPage");
    kdk_dia_data_free(node);

    this->buttonText = "";
    emit signalSendClicpText();
}

void SelectWidget::slShowContextMenu()
{
    //点击图标后更新位置并显示此菜单
    settingRightClickMenu->move(cursor().pos());
    settingRightClickMenu->exec();
}

QString SelectWidget::getButtonText()
{
    return buttonText;
}

int SelectWidget::getCurrentId()
{
    return promptId;
}

bool SelectWidget::eventFilter(QObject *o, QEvent *e)
{
    if (e->type() == QEvent::ActivationChange)
        {
            if(QApplication::activeWindow() != this  && QApplication::activeWindow() != m_selectMoreCommandWidget  )
            {
                this->hide();
                m_selectMoreCommandWidget->hide();
            }
        }
    return QWidget::event(e);
}

void SelectWidget::moveEvent(QMoveEvent *event)
{
    //基类调用
    QWidget::moveEvent(event);
    if(m_selectMoreCommandWidget->isVisible() == true)
    {
        // 获取新的位置
        QPoint newPos = event->pos();
        m_selectMoreCommandWidget->move(newPos.x()+m_moreCommandStartPos,newPos.y()+this->height()+10);

    }
}

//需求:插入文字到光标位置
void SelectWidget::insertText(const QString &text)
{
    QDBusInterface interface("org.ukui.inputmethod",
                             "/commitstring",
                             "org.ukui.inputmethod.commitstring",
                             QDBusConnection::sessionBus());

    interface.call("CommitString", text);
}

void SelectWidget::closeWidgetAndinstructPage(int x, int y)
{
    //在点击非划词区域时隐藏划词界面
    //TODO:Bug界面隐藏后菜单上下文点击会失效
    emit sigDisableMorePage();
    m_selectMoreCommandWidget->setVisible(false);
    this->hide();
}


void SelectWidget::showScribeWordsAtCursorPosition()
{
    KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
    kdk_dia_upload_default(node, "send_scribe_words_waken_event", "scribeWordsPage");
    kdk_dia_data_free(node);

    close();
    showSelectWidgetWithAnimation();

    return;
}

void SelectWidget::initAnimation()
{
    m_animation = new QPropertyAnimation(this, "windowOpacity");
    m_animation->setDuration(300);
    m_animation->setStartValue(0.0);
    m_animation->setEndValue(1.0);
    m_animation->setEasingCurve(QEasingCurve::OutInQuad);

    return;
}

void SelectWidget::initMenu()
{
    //添加菜单选项
    //菜单
    settingRightClickMenu= new QMenu(this);
    settingRightClickMenu->setAccessibleName("kylin-aiassistant_QMenu_settingRightClickMenu");
    //发送指令
    sendAction = new QAction(tr("Send to AI Assistant"));
    settingRightClickMenu->addAction(sendAction);
    connect(sendAction,&QAction::triggered,this,[&](){
        slSettingButtonClicked();
    },Qt::AutoConnection);
    //主页
    homePageAction = new QAction(tr("kylin-aiassistant HomePage"));
    settingRightClickMenu->addAction(homePageAction);
    connect(homePageAction,&QAction::triggered,this,[&](){
        emit sigHomePageShow();
    },Qt::AutoConnection);

    settingRightClickMenu->addSeparator();

    //关闭划词选项
    disableAction = new QAction(tr("Disable Floating Bar For Scribe Words"));
    settingRightClickMenu->addAction(disableAction);
    connect(disableAction,&QAction::triggered,this,[&](){
          emit sigDisableScribe();
    },Qt::AutoConnection);

    settingRightClickMenu->addSeparator();

    //设置
    settingAction = new QAction(tr("Setting"));
    settingRightClickMenu->addAction(settingAction);
    connect(settingAction,&QAction::triggered,this,[&](){
        emit sigSettingShow();
    },Qt::AutoConnection);
    //关闭
    closeAction = new QAction(tr("Close"));
    connect(closeAction,&QAction::triggered,this,[&](){
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "send_close_scribe_words_click_event", "scribeWordsPage");
        kdk_dia_data_free(node);
        this->hide();
    },Qt::AutoConnection);
    settingRightClickMenu->addAction(closeAction);
}


void SelectWidget::showSelectWidgetWithAnimation()
{
    //清理并重新生成quickWidget内容
    if(m_quickWidget) {
        m_quickWidget->deleteLater();
        m_quickWidget = nullptr;
    }

    initQmlSelectWidget();

    QQuickItem *item=m_quickWidget->rootObject();
    if (item) {
        QMetaObject::invokeMethod(item, "onUpdateNewMessage");

    } else {
        return;
    }

    this->setWindowOpacity(0.0);

    // 获取鼠标光标位置
    QPoint cursorPos = QCursor::pos();
#ifdef UKUI_WINDOWHELPER_SUPPORT
        cursorPos.setX(0);
        cursorPos.setY(0);
        m_ukuiWindowHelper->openUnderCursor(cursorPos);
#else
        QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
        // 调整划词弹出窗口位置，确保屏幕范围内可见，让0 <= x <= availableGeometry.right() - this->width(), 0 <= y <= availableGeometry.bottom() - this->height(),
        int x = qBound(0, cursorPos.x(), availableGeometry.right() - this->width());
        int y = qBound(0, cursorPos.y(), availableGeometry.bottom() - this->height());
        move(x, y);
#endif
    this->show();
    m_animation->start();

    return;
}

bool SelectWidget::isIncludeMenuPage(int x, int y)
{
    if(settingRightClickMenu){
        QRect geoMenuRect = settingRightClickMenu->geometry();
        return geoMenuRect.contains(x,y);
    }

}

bool SelectWidget::isIncludeMoreCommandWidget(int x, int y)
{
    if(m_selectMoreCommandWidget){
        QRect moreCmdWidget = m_selectMoreCommandWidget->geometry();
        return moreCmdWidget.contains(x,y);
    }

}
