/*
 * 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 "cmainwnd.h"

#include <usermanual.h>
#include <kysdk/kysdk-system/libkysysinfo.h>
#include <QWidget>
#include <QScreen>
#include <QMessageBox>

#include "windowhelper.h"

const QStringList g_supportDocFormats = {"txt", "pdf", "docx", "pptx"};
const QStringList g_supportPicFormats = {"bmp", "jpe", "jpeg", "jpg", "pbm", "pgm", "png", "ppm", "tiff", "webp"};

CMainWnd::CMainWnd(QWidget *parent)
    : KWidget(parent)
{
    disconnect(this->windowButtonBar(), &KWindowButtonBar::doubleClick, 0, 0);
    disconnect(this->iconBar(), &KIconBar::doubleClick, 0, 0);
    m_isFirstShow = true;

    //设置窗口标题
    this->setWindowTitle(tr("kylin-aiassistant"));
    this->setWindowIcon(QIcon::fromTheme("kylin-ai-assistant"));

#ifdef UKUI_WINDOWHELPER_SUPPORT
    m_ukuiWindowHelper = new UkuiWindowHelper(this);
    m_ukuiWindowHelper->removeTitleBar();
    // AI 助手在任务栏有常住入口后，需要跳过任务栏显示
    m_ukuiWindowHelper->setSkipTaskBar(true);

#else
    connect(kdk::WindowManager::self(), &kdk::WindowManager::windowAdded, this, [=](const kdk::WindowId &window_id) {
        if(getpid() == kdk::WindowManager::getPid(window_id) && m_window_id == 0)
        {
            m_window_id = window_id.toULongLong();
            // 旧版窗管接口依赖kdk::WindowManager::windowAdded信号响应之后拿到窗口id
            KyInfo() << "---------m_window_id-------" << m_window_id;
            initTopping(); // 初始化置顶
        }
    });
    kdk::UkuiStyleHelper::self()->removeHeader(this);
#endif
    initTitleBar();
    m_msgPane = new CMsgPane();
    initWindowMode();
    initLoadingIcon();
}

CMainWnd::~CMainWnd()
{
}

void CMainWnd::createAllChildWnd()
{
#define NEW_OBJECT(pObj, TYPE) \
    if(NULL == pObj)           \
    {                          \
        pObj = new TYPE(this); \
    }

    NEW_OBJECT(m_dbusOperator, KADBusOperator);
    m_settingPage = new SettingDialog(this);
    // fix bug #301003 【需求33947】【AI助手】设置窗口支持拖拽调整大小，双击后窗口最大化
    // 问题描述：由于sdk KWidget嵌套KWidget的实现机制问题，直接通过构造函数setFixedSize会失效
    // 解决方案：为避免此问题，采用规避方案：1. 不在构造函数中调用setFixedSize，改为在对象创建后设置固定大小 2. 在构造函数中首先调用resize，否则获取宽高时会出现问题
    m_settingPage->setFixedSize(744, 460);
    m_settingPage->setAccessibleName("kylin-aiassistant_SettingDialog_m_settingPage");
    SettingDialog::sharedInstance = m_settingPage;

    NEW_OBJECT(m_mainQml, QQuickWidget);
    NEW_OBJECT(m_closeModeWidget,CloseModeWidget);
    NEW_OBJECT(m_stackWdiget, QStackedWidget);
    NEW_OBJECT(m_introWidget, IntroductionView);



    return;
}

void CMainWnd::initCtrl()
{
    //禁止父窗口样式影响子控件样式
    setAttribute(Qt::WA_StyledBackground);
    //设置主窗体颜色，修改this->palette可能会导致其他问题，bug #I9QUZV
    QPalette pale;
    pale.setColor(QPalette::Base, QColor("#F5F5F5"));
    this->setPalette(pale);
    //焦点不在窗口上时鼠标悬浮可显示tooltips
    this->setAttribute(Qt::WA_AlwaysShowToolTips);

    //标题栏菜单
    QMenu *menuConfig = new QMenu(this);
    menuConfig->setAccessibleName("kylin-aiassistant-QMenu_menuConfig");
    windowButtonBar()->menuButton()->setMenu(menuConfig);

    // 首先断开所有与menuButton相关的连接
    disconnect(windowButtonBar()->menuButton(), nullptr, nullptr, nullptr);
    // 连接clicked信号，使用Qt::UniqueConnection确保不会重复连接
    connect(windowButtonBar()->menuButton(), &QToolButton::clicked, this, [&](){
        m_msgPane->sendFocusChanged();
        // 检查弹窗是否存在
        if (m_msgPane->getPopupExist()) {
            return;
        }

        // 手动显示菜单，并指定位置（通常在按钮下方）
        QToolButton* menuButton = windowButtonBar()->menuButton();
        if (menuButton && menuButton->menu()) {
            menuButton->menu()->exec(menuButton->mapToGlobal(QPoint(0, menuButton->height())));
        }
    }, Qt::UniqueConnection);

    QActionGroup * actGroup = new QActionGroup(this);
    actGroup->setExclusive(true);
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    //视图模式
    QMenu * viewMode = new QMenu;
    viewMode->setAccessibleName("kylin-aiassistant-QMenu_viewMode");
    viewMode->menuAction()->setText(tr("ViewModel"));
    QAction * sidebarMode = new QAction(tr("SidebarMode"), this);
    sidebarMode->setCheckable(true);
    if(winMode == WINDOW_MODE_SIDEMODE){
        sidebarMode->setChecked(true);
    }
    actGroup->addAction(sidebarMode);
    connect(sidebarMode, &QAction::triggered, this, &CMainWnd::switchToSideMode);



    QAction * wndMode = new QAction(tr("WindowMode"), this);
    wndMode->setCheckable(true);
    if(winMode == WINDOW_MODE_WINDOWMODE){
        wndMode->setChecked(true);
    }
    actGroup->addAction(wndMode);
    connect(wndMode, &QAction::triggered, this, &CMainWnd::switchToWindowMode);

    viewMode->addActions(actGroup->actions());

    //根据主题版本判断是否开启大窗口模式切换入口
    menuConfig->addMenu(viewMode);

    //设置
    confAction = new QAction(tr("Setting"), this);
    menuConfig->addAction(confAction);

    //帮助
    QAction * helpAct = new QAction(tr("Help"), this);
    //2412 产品要求隐藏帮助按钮
    menuConfig->addAction(helpAct);
    connect(helpAct, &QAction::triggered, this, &CMainWnd::onShowHelp);
    QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_F1), this);
    connect(shortcut, &QShortcut::activated, this, &CMainWnd::onShowHelp);

    //关于
    QAction * aboutAct = new QAction(tr("About"), this);
    menuConfig->addAction(aboutAct);
    connect(aboutAct, &QAction::triggered, this, &CMainWnd::onShowAbout);

    //退出
    QAction *act_exit = new QAction(tr("Exit"), this);
    menuConfig->addAction(act_exit);
    connect(act_exit, &QAction::triggered, this, &CMainWnd::onExitActionTriggled);

    // qml主页面
    m_mainQml->rootContext()->setContextProperty("globals",Globals::getinstance());
    m_mainQml->rootContext()->setContextProperty("msgPane",m_msgPane);
    m_mainQml->rootContext()->setContextProperty("commandTemplateListModel", CommandTemplateList::getInstance());
    //注册可用模型列表到qml中
    m_mainQml->rootContext()->setContextProperty("modelItemModel", ModelItemListModel::getInstance());
    if (m_msgPane->getIsChatReady()){
        if(g_configManager->getConfigValue("is-first-install").toBool()){
            m_stackWdiget->setCurrentWidget(m_introWidget);
        } else {
            m_stackWdiget->setCurrentWidget(m_mainQml);
        }

        m_mainQml->setSource(QUrl(QStringLiteral("qrc:/qml/qml/main.qml")));
        initWindowMode();
    } else {
        m_mainQml->setSource(QUrl(QStringLiteral("qrc:/qml/qml/LoadImage.qml")));
    }
    // 监听全局焦点变化
    connect(qApp, &QApplication::focusChanged, this, &CMainWnd::onFocusChanged);

    m_addFileMenu = new QMenu(this);
    m_addFileMenu->setAccessibleName("kylin-aiassistant-QMenu_addFileMenu");
    m_addFileMenu->setFixedWidth(128);
    QAction *addImageAct = m_addFileMenu->addAction(QIcon(":/icon/icon/addImage.svg"), tr("Add Image"));
    QAction *addFileAct = m_addFileMenu->addAction(QIcon(":/icon/icon/addFile.svg"), tr("Add File"));

    connect(m_msgPane, &CMsgPane::sigShowAddFileMenu, this, &CMainWnd::onShowAddFileMenu);
    connect(m_addFileMenu, &QMenu::aboutToHide, this, &CMainWnd::onAddFileMenuAboutToHide);
    connect(addImageAct, &QAction::triggered, this, [this](){
        qInfo() << "add image selected";
        this->onOpenFile(1);
    });
    connect(addFileAct, &QAction::triggered, this, [this](){
        qInfo() << "add document selected";
        this->onOpenFile(2);
    });

}

void CMainWnd::onShowAddFileMenu()
{
    // 获取主窗口的位置
    QRect geometry = this->geometry();
    int x = geometry.x();
    int y = geometry.y();

    // 计算固定位置
    int menuX = x + this->width() - 134;
    int menuY = y + this->height() - 152;

    m_addFileMenu->exec(QPoint(menuX, menuY));
    onAddFileMenuAboutToHide();
}

void CMainWnd::onAddFileMenuAboutToHide()
{
    qInfo() << "add file menu is about to hide";
    Q_EMIT m_msgPane->sigAddFileMenuHide();

}

void CMainWnd::initSolts()
{
    connect(confAction, SIGNAL(triggered()), this, SLOT(onConfActionTriggered()));

    connect(m_dbusOperator, &KADBusOperator::sigShowOrHideView, [this] {
        showOrHideWindow();
    });
    connect(m_msgPane, &CMsgPane::sigSetup, [this] {
        onConfActionTriggered();
    });
    connect(m_btnSideBar, &QPushButton::clicked, this, &CMainWnd::onSideBarBtnClicked);
    connect(m_btnBack, &QPushButton::clicked, this, &CMainWnd::onBackBtnClicked);
    connect(m_msgPane,&CMsgPane::showPage,this,&CMainWnd::onPageChanged);
    connect(m_msgPane, &CMsgPane::sigLoadMyMessageBox, this, &CMainWnd::onShowCustomMessageBox);
    connect(this, &CMainWnd::sigThemeChanged, m_settingPage, &SettingDialog::onThemeChanged);
    connect(m_msgPane,&CMsgPane::showSettingPage,this,&CMainWnd::onConfActionTriggered);
    connect(m_settingPage, &SettingDialog::sigSetCloudModel, m_msgPane, &CMsgPane::onSetCloudModel);
    // 连接信号与槽
   connect(m_msgPane, &CMsgPane::activateMainWindowSignal, this, &CMainWnd::onActivateMainWindow);
   connect(m_msgPane, &CMsgPane::sigSaveAs, this, &CMainWnd::onSaveAs);
   connect(m_msgPane, &CMsgPane::sigOpenFile, this, &CMainWnd::onOpenFile);

   connect(m_closeModeWidget,&CloseModeWidget::sigHideCurrentApp,this,[&](){
       this->hide();
   });
   connect(m_closeModeWidget,&CloseModeWidget::sigCurrentCloseMode,m_settingPage,&SettingDialog::slUpdateCloseMode);
   connect(m_closeModeWidget,&CloseModeWidget::rejected,this,[&](){
       isCloseBoxOpen = false;
   });

   connect(m_msgPane, &CMsgPane::chatInitCompleted, this, [&](){
       if(g_configManager->getConfigValue("is-first-install").toBool() == true && m_msgPane->getIsChatReady() == true){
           m_stackWdiget->setCurrentWidget(m_introWidget);
       } else {
           m_stackWdiget->setCurrentWidget(m_mainQml);
       }

       m_mainQml->setSource(QUrl(QStringLiteral("qrc:/qml/qml/main.qml")));
       initWindowMode();
       // 处理初次未启动发送的图片或文档
       handleSendFile();
   });
   connect(m_introWidget,&IntroductionView::openUKUIControlCenterView,m_msgPane,&CMsgPane::openUkuiControlCenter);
   connect(m_introWidget, &IntroductionView::openUKUIControlCenterView, [this] {
       m_stackWdiget->setCurrentWidget(m_mainQml);
   });
   connect(m_introWidget, &IntroductionView::showMainQmlPage, [this] {
       m_stackWdiget->setCurrentWidget(m_mainQml);
   });
   connect(m_stackWdiget, &QStackedWidget::currentChanged, [this](int index) {
       // 获取当前窗口
       QWidget *currentWidget = m_stackWdiget->widget(index);
       if (currentWidget == m_introWidget) {
           windowButtonBar()->menuButton()->setEnabled(false);
           m_btnSideBar->setEnabled(false);
       } else {
           windowButtonBar()->menuButton()->setEnabled(true);
           m_btnSideBar->setEnabled(true);
       }
   });

    return;
}


void CMainWnd::initLayout()
{

    QHBoxLayout *layoutRMain = new QHBoxLayout(baseBar());
    m_stackWdiget->addWidget(m_introWidget);
    m_stackWdiget->addWidget(m_mainQml);
    m_stackWdiget->setCurrentWidget(m_mainQml);
    layoutRMain->addWidget(m_stackWdiget);
    layoutRMain->setSpacing(0);
    layoutRMain->setMargin(0);
    layoutRMain->setContentsMargins(0, 0, 0, 0);

    KWindowButtonBar *button_bar = windowButtonBar();

    disconnect(button_bar->closeButton(), &QPushButton::clicked, 0, 0);
    connect(button_bar->closeButton(), &QPushButton::clicked, this,[&](){
        m_msgPane->sendFocusChanged();
        if (m_msgPane->getPopupExist()) {
            return;
        }
        bool isHideTray = g_configManager->getConfigValue("is-hide-tray").toBool();
        KyInfo() << "====mainwnd closebutton clicked====isHideTray:" << isHideTray;
        if(isHideTray){
            this->hide();
        } else {
            this->close();
        }
    });

    //窗口模式存在抖动现象，后续解决
    m_mainQml->setResizeMode(QQuickWidget::ResizeMode::SizeRootObjectToView);
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    if(winMode == 2){
        switchToSideMode();
    }else if (winMode == 3){
        switchToWindowMode();
    }else{
        switchToSideMode();
    }

    //关于窗口初始化
    appVersion = getAiAssistantVersion();
    aboutWindow = new kdk::KAboutDialog(this,
       QIcon::fromTheme("kylin-ai-assistant"),
       tr(appShowingName.toLocal8Bit()),
       tr("Version: ") + appVersion /*APP_VERSION*/
    );
    aboutWindow->setAccessibleName("kylin-aiassistant_kdk::KAboutDialog_aboutWindow");
    aboutWindow->setBodyText(tr("kylin-aiassistant is a tool to help users..."));
    aboutWindow->setBodyTextVisiable(false);
}

QScreen* CMainWnd::getCurrentScreen()
{
#ifdef UKUI_WINDOWHELPER_SUPPORT
    QScreen *screen = m_ukuiWindowHelper->getCurrentScreenBlocking();
#else
    QScreen *screen = QGuiApplication::screenAt(QCursor::pos());
#endif

    return screen;
}

void CMainWnd::switchToSideMode()
{
    KyInfo() << "====switchToSideMode====";
    QScreen *currentScreen = getCurrentScreen();
    if (currentScreen == nullptr) {
        KyInfo() << "current screen is nullptr";
        return;
    }

    m_currentScreen = currentScreen;
    setSideModePos();

    m_isMouseDragMove = false; //恢复窗口不触发移动记住位置
    m_msgPane->m_windowMode = WINDOW_MODE_SIDEMODE;
    g_configManager->updateNonCriticalConfig("win-mode", WINDOW_MODE_SIDEMODE);

    setMovable(false);
    iconBar()->setVisible(false);
    m_btnSideBar->setVisible(true);
    return;
}

void CMainWnd::switchToWindowMode()
{
    KyInfo() << "====switchToWindowMode====";
    Q_EMIT m_msgPane->changeWinModeToChat(3);

    // 将页面大小和页面切换前置，解决页面切换滞后性
    // 根据活跃模块内容并进行对应的显示
    ActiveModule module = m_msgPane->getCurrentActiveModule();
    if (ActiveModule::MODULE_PLUGIN == module) {
        Q_EMIT m_msgPane->showPage(4);
    } else if (ActiveModule::MODULE_CHAT == module) {
        Q_EMIT m_msgPane->showPage(4);
    }

    Q_EMIT m_msgPane->changeToWinMode(568 - windowButtonBar()->height());

    m_isMouseDragMove = false; //恢复窗口不触发移动记住位置
    m_msgPane->m_windowMode = WINDOW_MODE_WINDOWMODE;
    g_configManager->updateNonCriticalConfig("win-mode", WINDOW_MODE_WINDOWMODE);
    setMovable(true);

    iconBar()->setVisible(true);
    m_btnSideBar->setVisible(false);
    m_btnBack->setVisible(false);

    setMinimumSize(WINDOW_MIN_WIDTH, WINDOW_MIN_HEIGHT);
    resize(WINDOW_WIDTH, WINDOW_HEIGHT);
    setWindowModePos();
    return;
}

void CMainWnd::setSideModePos()
{
    KyInfo() << "====setSideModePos====";
    if (m_currentScreen == nullptr) {
        KyInfo() << "m_currentScreen is nullptr, cannot set side mode pos";
        return;
    }

    // 将页面大小和页面切换前置，解决页面切换滞后性
    Q_EMIT m_msgPane->changeWinModeToChat(2);

    QRect screenRect = m_currentScreen->availableGeometry();
    KyInfo() << "====currentScreen====name" << m_currentScreen->name();
    KyInfo() << "====availableGeometry====x:" << screenRect.x() << "y:" << screenRect.y()
             << "width:" << screenRect.width() << "height:" << screenRect.height()
             << "right:" << screenRect.right() << "top:" << screenRect.top();


    // 通过信号实现控制前端页面大小
    Q_EMIT m_msgPane->changeToSideMode(SIDEBAR_WIDTH, screenRect.height() - windowButtonBar()->height() - 2 * WINDOW_MARGIN);

    //根据活跃模块内容切换到对应显示界面
    ActiveModule module = m_msgPane->getCurrentActiveModule();
    if (ActiveModule::MODULE_PLUGIN == module) {
        Q_EMIT m_msgPane->showPage(2);
    } else if(ActiveModule::MODULE_CHAT == module) {
        Q_EMIT m_msgPane->showPage(0);
    }

    setFixedSize(SIDEBAR_WIDTH, screenRect.height() - 2 * WINDOW_MARGIN );

    int x = 0;
    int y = screenRect.top() + WINDOW_MARGIN;
    QString systemLang = QLocale::system().name();
    if (systemLang == "ug_CN" || systemLang == "ky_KG" || systemLang == "kk_KZ") {
        x = screenRect.x() + WINDOW_MARGIN;
    } else {
        x = screenRect.right() - SIDEBAR_WIDTH - WINDOW_MARGIN;
    }

    KyInfo() << "====setGeometry====x:" << x << "y:" << y << "width:" << SIDEBAR_WIDTH << "height:" << (screenRect.height() - 2 * WINDOW_MARGIN);
    this->setGeometry(QRect(x, y, SIDEBAR_WIDTH, screenRect.height() - 2 * WINDOW_MARGIN));

    // 新手引导更新大小
    if (m_introWidget) {
        m_introWidget->setFixedSize(this->size());
    }

    return;
}

void CMainWnd::setWindowModePos()
{
    //窗口在当前屏幕居中
    QScreen *currentScreen = getCurrentScreen();
    if (currentScreen == nullptr) {
        KyInfo() << "currentScreen is nullptr, cannot set window mode pos";
        return;
    }

    m_currentScreen = currentScreen;
    QRect screenRect = currentScreen->availableGeometry();
    KyInfo() << "====currentScreen====name" << m_currentScreen->name();
    KyInfo() << "====availableGeometry====x:" << screenRect.x() << "y:" << screenRect.y()
             << "width:" << screenRect.width() << "height:" << screenRect.height();

    int x = screenRect.x() + (screenRect.width() - this->width()) / 2;
    int y = screenRect.y() + (screenRect.height() - this->height()) / 2;
    KyInfo() << "====setGeometry====x:" << x << "y:" << y << "width:" << this->width() << "height:" << this->height();
    this->setGeometry(QRect(x, y, this->width(), this->height()));
    return;
}

void CMainWnd::initTrayIcon()
{
    // 系统托盘
    m_trayIcon = new QSystemTrayIcon(this);
    m_trayIcon->setObjectName("kylin-aiassistant_QSystemTrayIcon_m_trayIcon");
    m_trayIcon->setToolTip(QString(tr("AI Assistant")));
    m_trayIcon->setIcon(QIcon::fromTheme("kylin-ai-assistant"));

    connect(m_trayIcon, &QSystemTrayIcon::activated, this, &CMainWnd::onTrayIconActivated);
    m_trayIcon->show();
}

void CMainWnd::initTrayIconMenu()
{
    m_trayIconMenu = new QMenu();
    m_trayIconMenu->setAccessibleName("kylin-aiassistant_QMenu_m_trayIconMenu");
    QAction * quitAction =  new QAction(tr("Quit"));
    connect(quitAction, &QAction::triggered, [&](){
        exit(0);
    });
    m_trayIconMenu->addAction(quitAction);
    m_trayIcon->setContextMenu(m_trayIconMenu);
}

void CMainWnd::initScribeWords()
{
    m_selectwid = new SelectWidget;
    m_selectwid->setAccessibleName("kylin-aiassistant_SelectWidget_m_selectwid");

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper *ukuiWindowHelper = new UkuiWindowHelper(this);
    ukuiWindowHelper->removeTitleBar();
#else
    kdk::UkuiStyleHelper::self()->removeHeader(this);
#endif

    m_selectclip = new Clipboard;
    m_selectclip->setObjectName("kylin-aiassistant_Clipboard_m_selectclip");
    selectTimer  = new QTimer;
    selectTimer->setInterval(30);
    connect(selectTimer,&QTimer::timeout,this,&CMainWnd::onStartSendSelectMsg,Qt::UniqueConnection);
    connect(m_msgPane, &CMsgPane::copyToClipboard, m_selectclip, &Clipboard::setText);
//    connect(m_msgPane, &CMsgPane::copyToClipboard, [=](){
//        TipWidget::showTip(tr("Copy Successful"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::copyToClipboard, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });
//    connect(m_msgPane, &CMsgPane::copyImageToClipboard, [=](){
//        TipWidget::showTip(tr("Copy Successful"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::copyImageToClipboard, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });

    connect(m_msgPane, &CMsgPane::copySuccess, [=](){
        m_msgPane->showTip(tr("Copy Successful"));
    });
    connect(m_msgPane, &CMsgPane::tipsContinueDialog, [=](){
        TipWidget::showTip(tr("Dialogue is being generated, please try again later"), 3000, QSize(120, 48), this, TipWidget::WARNING);
    });
//    connect(m_msgPane, &CMsgPane::sigLikeAction, [=](){
//        TipWidget::showTip(tr("Thanks for your feedback"), 3000, QSize(120, 48), this, TipWidget::OK);
//    });
    connect(m_msgPane, &CMsgPane::sigLikeAction, [=](){
        m_msgPane->showTip(tr("Thanks for your feedback"));
    });
    connect(m_selectwid, &SelectWidget::sigbuttontext, this, &CMainWnd::handleClicpText);
    connect(m_selectwid, &SelectWidget::signalSendClicpText, this, &CMainWnd::handleClicpText);
    connect(m_selectwid, &SelectWidget::sigHomePageShow, this, [=]() {

        showView();
        m_selectwid->hide();
    });
    connect(m_selectwid, &SelectWidget::sigSettingShow, this, [=]() {
        onConfActionTriggered();
        m_selectwid->hide();
    });
    connect(m_selectwid, &SelectWidget::sigDisableScribe, this, [=]() {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "send_disable_scribe_words_click_event", "scribeWordsPage");
        kdk_dia_data_free(node);

        //关闭划词界面
        m_selectwid->hide();
        g_configManager->updateConfig("is-stroke-word", false);
        //设置界面关闭划词按钮
        if(m_settingPage)
        {
            m_settingPage->scribeWordsDisabled();
        }


    });
}

void CMainWnd::initScribeWordsSetting()
{
    // 点击是否禁用划词按钮
    connect(m_settingPage, &SettingDialog::sigEnableScribeWords, this,[=]{
         g_configManager->updateConfig("is-stroke-word", true);
    });
    connect(m_settingPage, &SettingDialog::sigDisableScribeWords, this, [=]() {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "send_setting_disable_scribe_words_button_click_event", "scribeWordsPage");
        kdk_dia_data_free(node);

        m_selectwid->hide();
        g_configManager->updateConfig("is-stroke-word", false);
    });
}

void CMainWnd::handleClicpText()
{
    QString buttonText = m_selectwid->getButtonText();
    QString clipText = m_selectclip->getClipText();
    int promptId = m_selectwid->getCurrentId();
    QString promptIconPath = CommandTemplateList::getInstance()->getPromptIconHighlightpath(promptId);
    if(clipText != "")
    {
        bool isEnd = m_msgPane->getIsEnd();
        if(!isEnd) //如果回答未结束则打断回答并启动计时器查询是否结束
        {
            m_msgPane->onStopReply();
            selectTimer->start();
        }
        else
        {
            QJsonObject jsonObjToWeb;
            jsonObjToWeb["msgHead"] = buttonText;
            jsonObjToWeb["promptId"] = promptId;
            jsonObjToWeb["promptIconPath"] = promptIconPath;
            QJsonDocument aiJsonSendWebDoc(jsonObjToWeb);
            QString jsonMsgHeadToWeb = aiJsonSendWebDoc.toJson(QJsonDocument::Indented);
            m_msgPane->onStartReplyingToChat();// 划词更新前端isReplying状态为true
            m_msgPane->onSendMsg(jsonMsgHeadToWeb, clipText);
            Q_EMIT m_msgPane->moveScrollBar();
        }
    }
    showView();
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        m_msgPane->showPage(1);
    }
    else if (curWinMode == 3)
    {
        m_msgPane->showPage(4);
    }
    Q_EMIT m_msgPane->moveScrollBar();
    Q_EMIT m_msgPane->sigClearTextArea();
    m_selectwid->hide();
}

void CMainWnd::onStartSendSelectMsg()
{
    QString buttonText = m_selectwid->getButtonText();
    QString clipText = m_selectclip->getClipText();
    int promptId = m_selectwid->getCurrentId();
    bool currentEnd =  m_msgPane->getIsEnd();
    QString promptIconPath = CommandTemplateList::getInstance()->getPromptIconHighlightpath(promptId);
    if(currentEnd)
    {
        QJsonObject jsonObjToWeb;
        jsonObjToWeb["msgHead"] = buttonText;
        jsonObjToWeb["promptId"] = promptId;
        jsonObjToWeb["promptIconPath"] = promptIconPath;
        QJsonDocument aiJsonSendWebDoc(jsonObjToWeb);
        QString jsonMsgHeadToWeb = aiJsonSendWebDoc.toJson(QJsonDocument::Indented);
        m_msgPane->onStartReplyingToChat();// 划词更新前端isReplying状态为true
        m_msgPane->onSendMsg(jsonMsgHeadToWeb, clipText);
        Q_EMIT m_msgPane->moveScrollBar();
        selectTimer->stop();
    }
}

void CMainWnd::onShotCutActionTriggled() { }

void CMainWnd::onAboutActionTriggled() { }

void CMainWnd::onExitActionTriggled()
{
     QCoreApplication::quit();

    return;
}

void CMainWnd::onTrayIconActivated(QSystemTrayIcon::ActivationReason reason)
{
    KyInfo() << "QSystemTrayIcon::ActivationReason" << reason;
    KyInfo() << "isHidden:" << this->isHidden()
             << "isMinimized" << this->isMinimized()
             << "isVisible" << this->isVisible()
             << "isMinimizeClicked" << isMinimizeClicked;

    if (reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::MiddleClick) {
        KTrackData *node = kdk_dia_data_init(KEVENTSOURCE_DESKTOP, KEVENT_CLICK);
        kdk_dia_upload_default(node, "system_tray_icon_click_event", "systemTrayIcon");
        kdk_dia_data_free(node);

        bool isMinimizedState = this->isMinimized() || isMinimizeClicked;

        if (this->isVisible()) {
            if (isMinimizedState) {
                showView(); // 可见且最小化
            } else {
                hideView();
            }
        } else {
            showView();
        }
    }

}

void CMainWnd::onAppRestarted(const QString &message)
{
    KyInfo() << "====onAppRestarted====message" << message;
    if (message == "running") {
        // 如果AI助手窗口被遮挡，则执行show操作，将窗口置于顶层
        if (!this->isActiveWindow()) {
            showView();
        }else {
            showOrHideWindow();
        }
    } else {//当做文件路径处理
        if (!this->isActiveWindow()) {
            showView();
        }

        QUrl url(message);
        m_peonyPluginFilePath = url.path();
        handleSendFile();
    }

}

void CMainWnd::closeEvent(QCloseEvent *e)
{
    bool isHideTray = g_configManager->getConfigValue("is-hide-tray").toBool();
    KyInfo() << "closeEvent===isHideTray:" << isHideTray;
    if(isHideTray){
        closeOrHidden();
    } else {
        e->accept();
    }
    return;
}

void CMainWnd::moveEvent(QMoveEvent *event)
{
    KWidget::moveEvent(event);
    KyInfo() << "Window position changed====old pos:" << event->oldPos() << "new pos:" << event->pos();
    return;
}

void CMainWnd::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
        // 处理回车键的事件
        //KyInfo() << "Enter key pressed!";
        m_msgPane->keyReturnPressed();
    }

    // 调用基类的 keyPressEvent()，以便处理其他按键事件
    KWidget::keyPressEvent(event);
}

bool CMainWnd::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::MouseButtonPress) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
        if (mouseEvent->button() == Qt::LeftButton) {
            m_msgPane->sendFocusChanged();
        }
    }
    if(event->type() == QEvent::Close){
        KyInfo() << "QEvent::Close!!!!!!!!!!";
        event->ignore();
        closeOrHidden();
    }
    return QWidget::eventFilter(obj, event);
}

void CMainWnd::showView()
{
    this->activateWindow();
    KyInfo() << "force Active Window";

    int curWinMode = m_msgPane->getCurWinMode();
    if (curWinMode == 2) { // 侧边栏模式
        QScreen *currentScreen = getCurrentScreen();
        if (currentScreen == nullptr) {
            KyInfo() << "current screen is nullptr";
            return;
        }

        m_currentScreen = currentScreen;
        setSideModePos();
    } else if (m_isFirstShow == true && curWinMode == 3) { // 窗口模式
        setWindowModePos();
    }

    this->show();
    this->raise();
    this->activateWindow();

    if(g_configManager->getConfigValue("is-first-install").toBool() == true && m_msgPane->getIsChatReady() == true){
        m_stackWdiget->setCurrentWidget(m_introWidget);
    } else if (m_settingPage != nullptr && isSettingOpen == true) {
        showSettingPage();
    }

    isMinimizeClicked = false;
    m_isFirstShow = false;

    m_mainQml->setFocus();
    KyInfo() << "showView end";

    return;
}

void CMainWnd::hideView()
{
    KyInfo() << "hideView";

    // 检查是否有活动的模态窗口
    if (QApplication::activeModalWidget()) {
        KyInfo() << "====modal dialog is active, preventing hide====";
        return;
    }

    KyInfo() << "---hide---";
    this->hide();
}

void CMainWnd::onFocusChanged(QWidget *oldWidget, QWidget *newWidget) {
    // 如果新窗口为空，说明 QWidget 失去焦点
    if (!newWidget) {
        m_msgPane->sendFocusChanged();
    }
}

void CMainWnd::slotToTop()
{
    qInfo() << "isTop " << m_isTop;

    m_msgPane->sendFocusChanged();
    if (m_msgPane->getPopupExist()) {
        return;
    }

    if(!m_isTop){
        keepWindowAbove(true);
        m_isTop = true;
        g_configManager->updateConfig("is-window-mode-topping", true);
    }else{
        keepWindowAbove(false);
        m_isTop = false;
        g_configManager->updateConfig("is-window-mode-topping", false);
    }

    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::slotToTopChangeWinMode()
{
    int curWinMode = m_msgPane->getCurWinMode();
    if(curWinMode == 2)
    {
        bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();
        if(m_isTop){
            keepWindowAbove(true);
            m_isTop = true;
        }
    }
    else if (curWinMode == 3){        // 窗口模式
        bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();
        if(isTopping){
            keepWindowAbove(true);
            m_isTop = true;
        }
    }
    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::onSideBarBtnClicked()
{
    m_msgPane->sendFocusChanged();
    if (m_msgPane->getPopupExist()) {
        return;
    }

    ActiveModule activateModule = m_msgPane->getCurrentActiveModule();
    if (activateModule == ActiveModule::MODULE_PLUGIN) {
        // 当前在侧边栏
        if (m_previousModule == ActiveModule::MODULE_CHAT) {
            // KyInfo() << "返回助手主页";
            Q_EMIT m_msgPane->showPage(1);
        } else {

        }

    } else {
        Q_EMIT m_msgPane->cancelVoiceStopReplying();//停止语音更新状态
        Q_EMIT m_msgPane->cancelSendAudio();//停止语音恢复UI
        // 切换到侧边栏
        m_previousModule = activateModule;
        Q_EMIT m_msgPane->showPage(2);
    }

    return;
}

void CMainWnd::onBackBtnClicked()
{
    m_msgPane->onBackBtnClicked();
}

void CMainWnd::onPageChanged(const int pageNumber)
{
    //在主页和侧边栏时无需显示返回按钮
    if(pageNumber == 0 || pageNumber ==1 || pageNumber == 2 || pageNumber ==4)
    {
        m_btnBack->setVisible(false);
    }

    //在非侧边栏界面需要显示侧边栏按钮
    if(pageNumber == 0 || pageNumber == 1)
    {
        m_btnSideBar->setVisible(true);
    }
    PageType newPage;
    //侧边栏模式控制前端显示页面 0显示全部 1显示主页面 2显示侧边栏 4窗口模式下显示主界面
    switch (pageNumber) {
    case 0:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    case 1:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    case 2:
        newPage = PageType::SHOW_SIDEBAR;
        pageNumber == 2;
        break;
    case 4:
        newPage = PageType::MAIN_PAGE_WINDOW_MODE;
        m_btnBack->setVisible(false);
        break;
    default:
        newPage = PageType::MAIN_PAGE_SIDEBAR_MODE;
        m_btnBack->setVisible(false);
        break;
    }

    g_currentPage = newPage; // 更新全局页面状态

}

void CMainWnd::onShowCustomMessageBox(const QVariantList &strings) {
    //KyInfo() << "删除确认弹窗打开";
    CustomMessageBox msgBox(this);
    msgBox.setMessage(tr("After deleting the conversation, it cannot be restored. Do you want to continue deleting?"));
    msgBox.setButtons(CustomMessageBox::OkButton | CustomMessageBox::CancelButton);
    //窗口居中
    msgBox.move(this->x() + (this->width() - msgBox.width()) / 2 , this->y() + (this->height() - msgBox.height()) / 2);
    KyInfo() << "*********** msgBox : " <<msgBox.x() << "  " << msgBox.y();

    isMsgBoxOpen = true;
    if (msgBox.exec() == QDialog::Accepted) {
        if (msgBox.clickedButton() == CustomMessageBox::OkButton) {
            // 用户点击了删除按钮，执行删除操作
            m_msgPane->deleteSessionList(strings);
        }
        isMsgBoxOpen = false;
    } else {
        //KyInfo() << "cancelClick";
        m_msgPane->modifyDialogueList(strings);
        isMsgBoxOpen = false;
    }
}

void CMainWnd::onConfActionTriggered()
{
    m_stackWdiget->setCurrentWidget(m_mainQml);
    showSettingPage();
    m_settingPage->resetIndex();
    isSettingOpen = true;
}

void CMainWnd::onCreateDialog()
{
    // 先保存当前会话
    m_msgPane->saveDialog();

    // 然后清除当前会话
    m_msgPane->clearDialog();

    // 隐藏历史会话界面
//    m_sideBar->hide();

    return;
}

void CMainWnd::showOrHideWindow()
{
    KyInfo() << "----showorhidewindow----isMinimizeClicked" << isMinimizeClicked << "----isMinimized----" << isMinimized();

    bool isMinimizedState = this->isMinimized() || isMinimizeClicked;

    if (this->isVisible()) {
        if (isMinimizedState) {
            showView(); // 可见且最小化
        } else {
            hideView();
        }
    } else {
        showView();
    }
}

void CMainWnd::onShowHelp()
{
    kdk::UserManual aiAssistantUserManual;
    if (!aiAssistantUserManual.callUserManual("kylin-aiassistant")) {
        qCritical() << "user manual call fail!";
    }
    return;
}

void CMainWnd::onShowAbout()
{
     aboutWindow->exec();
     return;
}

void CMainWnd::onActivateMainWindow()
{
    this->activateWindow();
    this->setFocus();
    m_mainQml->setFocus();
}

void CMainWnd::onSaveAs(const QString &base64Image)
{
    bool ok = false;
    QPixmap pixmap;

    // 去掉前缀
    QStringList parts = base64Image.split(",");
    if(parts.length() == 2)
    {
        QString imageData = parts.at(1);
        QByteArray byteArray = QByteArray::fromBase64(imageData.toLocal8Bit());
        pixmap.loadFromData(byteArray);
    }
    if(pixmap.isNull())
    {
        KyInfo() << "pixmap is null";
        return;
    }

    // 获取当前时间
    QDateTime currentTime = QDateTime::currentDateTime();
    QString formattedTime = currentTime.toString("yyyyMMdd_hhmmss");
    // 使用格式化后的时间作为文件名
    QString fileName = "aiassistant_" + formattedTime + ".png";
    QString path = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0);
    if(path.endsWith("/"))
    {
        path += fileName;
    }
    else
    {
        path += "/" + fileName;
    }

    //wayland环境下，构造函数必须加this， setModal(true)
    QFileDialog *fileDialog = new QFileDialog(this); // 设置窗口标题属性自定义
    fileDialog->setAccessibleName("kylin-aiassistant_QFileDialog_fileDialog");
    fileDialog->setModal(true);
    fileDialog->setNameFilter(QLatin1String("PNG(*.png);;JPE(*.jpe);;JPEG(*.jpeg);;JPG(*.jpg);;PBM(*.pbm);;PGM(*.pgm);;BMP(*.bmp);;PPM(*.ppm);;TIFF(*.tiff);;WEBP(*.webp)"));
    fileDialog->setDirectory(QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).at(0));
    fileDialog->setAcceptMode(QFileDialog::AcceptSave);
    fileDialog->selectFile(path);

    if(fileDialog->exec() == QFileDialog::Accepted)
    {
        QString savePath = fileDialog->selectedFiles().at(0);

        QFileInfo fileName = savePath;
        if(savePath.isNull())
        {
            return;
        }

        if(fileName.suffix().isNull())
        {
            savePath += QLatin1String(".png");
        }
        fileName = savePath;
        QString name = fileName.fileName();
        QString msg;
        QString message;
        if(!name.startsWith(QChar('.'), Qt::CaseInsensitive))
        {
            QFileInfo fileInfo(savePath);
            QStringList parts = base64Image.split(",");
            // 解码 Base64 字符串
            QByteArray decodedData;
            if(parts.length() == 2)
            {
                QString imageData = parts.at(1);
                decodedData = QByteArray::fromBase64(imageData.toLatin1());
            }
            if(fileInfo.suffix() == "jpeg"|| fileInfo.suffix() == "pgm"|| fileInfo.suffix() == "pbm" || fileInfo.suffix() == "ppm" || fileInfo.suffix() == "jpg"){
                // jpeg pgm pbm ppm jpg保存白色背景会填充黑色，额外处理，其中pgm pbm只支持黑白像素
                QImage originalImage;
                originalImage.loadFromData(decodedData);
                // 创建带有白色背景的新图像
                QImage newImage(originalImage.size(), QImage::Format_RGB32);
                newImage.fill(Qt::white);
                // 使用QPainter在新图像上绘制原图
                QPainter painter(&newImage);
                painter.drawImage(0, 0, originalImage);
                painter.end();
                // 保存图像
                if (newImage.save(savePath)) {
                    ok = true;
                } else {
                    ok = false;
                }
            }else if(fileInfo.suffix() == "jpe"){
                // 使用 QImage 加载解码后的数据
                // jpe保存会报错，额外处理
                QImage img;
                if (img.loadFromData(decodedData)) {
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                    if (img.save(savePath, "JPEG")) {
                        ok = true;
                    } else {
                        ok = false;
                    }
                } else {
                    qDebug() << "Failed to load image from decoded data.";
                }
                //ok = img.save(savePath, "JPEG");
            }else if(fileInfo.suffix() == "bmp"){
                // bmp保存白色背景会填充黑色，额外处理
                QImage image;
                image = image.convertToFormat(QImage::Format_RGB32);
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                if (image.loadFromData(decodedData)) {
                    // 保存为 .jpe 格式（实际上是 JPEG 格式）
                    if (image.save(savePath)) {
                        ok = true;
                    } else {
                        ok = false;
                    }
                } else {
                    qDebug() << "Failed to load image from decoded data.";
                }
            }else{
                ok = pixmap.save(savePath);
            }
        }
        if(ok)
        {
            QString pathNoFile = savePath.left(savePath.lastIndexOf(QLatin1String("/")));
            message = QObject::tr("Image saved as ") + savePath;
            msg = "<a href=\"" + savePath + "\">" + message + "</a>";
        }
        else
        {
            if(name.contains(QChar('/')))
            {
                msg = QObject::tr("file name can not contains '/'");
            }
            else if(name.startsWith(QChar('.'), Qt::CaseInsensitive))
            {
                msg = QObject::tr("can not save file as hide file");
            }
            else if(name.length() > 255)
            {
                msg = QObject::tr("can not save  because filename too long");
            }
            else
            {
//                message = QObject::tr("Error trying to save as ") + savePath;
//                msg = "<a href=\"" + savePath + "\">" + message + "</a>";
                msg = QObject::tr("Error trying to save as ") + savePath;
            }
            QMessageBox saveErrBox(QMessageBox::Warning, QObject::tr("Save Error"), msg);
            saveErrBox.exec();
        }
    }
    return;
    }

void CMainWnd::onOpenFile(int typeNum)
{
    FileType type = FileType(typeNum);
    //wayland环境下，构造函数必须加this， setModal(true)
    QFileDialog m_fileDialog(this);
    m_fileDialog.setModal(true);
    m_fileDialog.update();
    QList<QUrl> list = m_fileDialog.sidebarUrls();
    int sidebarNum = 8; //最大添加U盘数，可以自己定义
    QString home = QDir::homePath().section("/", -1, -1);
    QString mnt = "/media/" + home + "/";
    QDir mntDir(mnt);
    mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
    QFileInfoList filist = mntDir.entryInfoList();
    QList<QUrl> mntUrlList;
    for(int i = 0; i < sidebarNum && i < filist.size(); ++i)
    {
        QFileInfo fi = filist.at(i);
        //华为990、9a0需要屏蔽最小系统挂载的目录
        if(fi.fileName() == "2691-6AB8")
            continue;
        mntUrlList << QUrl("file://" + fi.filePath());
    }

    QFileSystemWatcher fsw(&m_fileDialog);
    fsw.addPath("/media/" + home + "/");
    connect(&fsw, &QFileSystemWatcher::directoryChanged, &m_fileDialog, [=, &sidebarNum, &mntUrlList, &list, &m_fileDialog](const QString path) {
        QDir wmntDir(path);
        wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList wfilist = wmntDir.entryInfoList();
        mntUrlList.clear();
        for(int i = 0; i < sidebarNum && i < wfilist.size(); ++i)
        {
            QFileInfo fi = wfilist.at(i);
            //华为990、9a0需要屏蔽最小系统挂载的目录
            if(fi.fileName() == "2691-6AB8")
                continue;
            mntUrlList << QUrl("file://" + fi.filePath());
        }
        m_fileDialog.setSidebarUrls(list + mntUrlList);
        m_fileDialog.update();
    });

    connect(&m_fileDialog, &QFileDialog::finished, &m_fileDialog, [=, &list, &m_fileDialog]() {
        m_fileDialog.setSidebarUrls(list);
    });

    //这行要添加，设置左侧导航
    m_fileDialog.setSidebarUrls(list + mntUrlList);
    //设置视图模式
    m_fileDialog.setViewMode(QFileDialog::Detail);
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    m_fileDialog.setFileMode(QFileDialog::ExistingFile);
    m_fileDialog.setOption(QFileDialog::HideNameFilterDetails);

    QString file_path;
    QString format;
    QString openFile = tr("Open Image");
    QStringList supportFile = { "txt","pdf","docx","pptx"};
    QStringList supportFormats = {  "bmp","jpe","jpeg","jpg","pbm","pgm","png","ppm","tiff","webp"};

    if(type == IMAGE)
    {
        //构造打开条件
        format = "(";
        for(const QString &str: supportFormats)
            format += "*." + str + " ";
        format += ");;";

        const QString supportFormatsClassify = "(*.bmp);;"
                                               "(*.jpe *.jpeg *.jpg);;"
                                               "(*.pbm);;"
                                               "(*.pgm);;"
                                               "(*.png);;"
                                               "(*.ppm);;"
                                               "(*.tiff);;"
                                               "(*.webp)";
        //所有类型都放在一起，类型名显示不全，故增加分层，将同一类型的放在一起，分层显示
        format = format + supportFormatsClassify;
        QVariant imagePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
        //打开文件夹中的图片文件
        file_path = m_fileDialog.getOpenFileName(this, openFile, imagePath.toString(), format);
    }
    else if(type == DOCUMENT)
    {
        format = "(";
        for(const QString &str: supportFile)
            format += "*." + str + " ";
        format += ");;";
        const QString supportFormatsClassify = "(*.txt);;"
                                               "(*.pdf);;"
                                               "(*.docx);;"
                                               "(*.pptx)";
        //所有类型都放在一起，类型名显示不全，故增加分层，将同一类型的放在一起，分层显示
        format = format + supportFormatsClassify;
        QVariant path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);

        //打开文件夹中的图片文件
        file_path = m_fileDialog.getOpenFileName(this, openFile, path.toString(), format);
}

    //空校验，点击“取消”
    if(file_path.isEmpty())
    {
        return;
    }
    // 目前文件对话框无法限制不能选中超过一个文件，多选的时候只上传第一张
//    else if(file_path.size() > 1)
//    {
//        onShowErrorMoreImage();
//        return;
//    }
    else
    {
        QFileInfo fileInfo(file_path);
        //判断文件后缀
        if(!supportFormats.contains(fileInfo.suffix().toLower()) && !supportFile.contains(fileInfo.suffix().toLower()))
        {
            if(type == IMAGE)
            {
                m_msgPane->onShowErrorFormatImage();
            }
            else if(type == DOCUMENT)
            {
                m_msgPane->onShowErrorFormatFile();
            }
            return;
        }
        else
        {
            if(type == IMAGE)
            {
                m_msgPane->onShowImage(file_path, 1);
            }
            else if(type == DOCUMENT)
            {
                m_msgPane->onShowDocument(file_path);
            }
        }
    }
}

void CMainWnd::onShowScribeWord()
{
    //如果禁用划词则直接返回
    bool isSelectDisable = g_configManager->getConfigValue("is-stroke-word").toBool();
//    KyInfo() << "当前禁用划词显示的标志位为"<< isSelectDisable;
    if(!isSelectDisable){
        return;
    }

    // 处理 v11 环境下划词显示异常问题
//    if(isWayland){
////        WindowManager::setOpenUnderCursor(m_selectwid->windowHandle());
//        m_selectwid->show();
//    }
//    else{
//        m_selectwid->showScribeWordsAtCursorPosition();
//    }
    KyInfo() << "=======m_selectwid->isVisible()======" << m_selectwid->isVisible();
    if (m_selectwid->isVisible() == true) {
        m_selectwid->closeWidgetAndinstructPage(1,1);
    } else {
        m_selectwid->showScribeWordsAtCursorPosition();
        m_msgPane->sendFocusChanged();

        if(m_selectclip)
        {
            KyInfo() << "current selectClip message:" << m_selectclip->getClipText();
            if(m_selectclip->getClipText() == "" || m_selectclip->getClipText() == "\n" || m_selectclip->getClipText().isEmpty() || m_stackWdiget->currentWidget() == m_introWidget)
            {
                m_selectwid->slUpdateSelectEnableStatus(false);
            }
            else
            {
                m_selectwid->slUpdateSelectEnableStatus(true);
            }
            if(m_stackWdiget->currentWidget() == m_introWidget)
            {
                m_selectwid->slUpdateSettingActionStatus(false);
            }
            else
            {
                m_selectwid->slUpdateSettingActionStatus(true);
            }
        }
    }


}

void CMainWnd::initPosition()
{
    QScreen *currentScreen = getCurrentScreen();
    if (currentScreen == nullptr || currentScreen->availableGeometry().isEmpty()) {
        KyInfo() << "11111====current screen is null, return====";
        return;
    }

    m_currentScreen = currentScreen;
    Globals::scaleFactor = currentScreen->devicePixelRatio();

    // 屏幕的分辨率或可用显示区域变化
    m_availableGeometryChangedConnection = connect(m_currentScreen, &QScreen::availableGeometryChanged, this, [this](const QRect &geometry) {
        KyInfo() << "22222====availableGeometryChanged====" << geometry;
        adjustForScreenChanged();
    });

    // 主屏变化
    connect(qApp, &QApplication::primaryScreenChanged, this, [this](QScreen *newPrimaryScreen) {
        if (newPrimaryScreen == nullptr || newPrimaryScreen->availableGeometry().isEmpty()) {
            KyInfo() << "33333====primaryScreen is null, ignore====";
            return;
        }

        KyInfo() << "33333====primaryScreenChanged====" << newPrimaryScreen->name() << newPrimaryScreen->availableGeometry();
        // 检查当前屏幕是否还存在于屏幕列表中
        QList<QScreen *> allScreens = QGuiApplication::screens();
        bool currentScreenExists = allScreens.contains(m_currentScreen);

        if (!currentScreenExists) {
            KyInfo() << "33333====The current screen has been removed====";
            m_currentScreen = getCurrentScreen();
            if (m_currentScreen == nullptr || m_currentScreen->availableGeometry().isEmpty()) {
               KyInfo() << "33333====get current screen failed====" << m_currentScreen;
               m_currentScreen = newPrimaryScreen;
            }

            KyInfo() << "33333====updated to the new current screen====" << m_currentScreen->name();
        } else {
            KyInfo() << "33333====The current screen still exists====" << m_currentScreen->name();
        }

        disconnect(m_availableGeometryChangedConnection);
        Globals::scaleFactor = m_currentScreen->devicePixelRatio();
        adjustForScreenChanged();

        m_availableGeometryChangedConnection = connect(m_currentScreen, &QScreen::availableGeometryChanged, this, [this](const QRect &geometry) {
           KyInfo() << "44444====availableGeometryChanged====" << geometry;
           adjustForScreenChanged();
        });
    });

    // 屏幕被添加
    connect(qApp, &QGuiApplication::screenAdded, this, [=](QScreen *screen){
        KyInfo() << "55555====screenAdded====ignore";
    });
    // 屏幕被移除
    connect(qApp, &QGuiApplication::screenRemoved, this, [=](QScreen *screen){
        KyInfo() << "66666====screenRemoved====";
        if (screen == nullptr || screen->availableGeometry().isEmpty()) {
            KyInfo() << "66666====screen is null, ignore=====";
            return;
        }

        // 检查当前屏幕是否还存在于屏幕列表中
        QList<QScreen *> allScreens = QGuiApplication::screens();
        bool currentScreenExists = allScreens.contains(m_currentScreen);

        if (currentScreenExists == false) {
           KyInfo() << "66666====The current screen has been removed====";
           m_currentScreen = QGuiApplication::primaryScreen();
           if (m_currentScreen == nullptr || m_currentScreen->availableGeometry().isEmpty()) {
               KyInfo() << "66666====get current screen failed, return====";
               return;
           }

           KyInfo() << "66666====updated to the new current screen====" << m_currentScreen->name();
        } else {
           KyInfo() << "66666====The current screen still exists====" << m_currentScreen->name();
        }

        disconnect(m_availableGeometryChangedConnection);
        Globals::scaleFactor = m_currentScreen->devicePixelRatio();
        adjustForScreenChanged();

        m_availableGeometryChangedConnection = connect(m_currentScreen, &QScreen::availableGeometryChanged, this, [this](const QRect &geometry) {
           KyInfo() << "77777====availableGeometryChanged====" << geometry;
           adjustForScreenChanged();
        });
    });

    return;
}

void CMainWnd::adjustForScreenChanged()
{
    int curWinMode = m_msgPane->getCurWinMode();
    if (curWinMode == 2) { // 仅处理侧边栏模式
        setSideModePos();
    }

    return;
}

void CMainWnd::initTopping()
{
    bool isTopping = g_configManager->getConfigValue("is-window-mode-topping").toBool();

    qInfo() << "isTopping " << isTopping;

    if(isTopping){
        m_isTop = true;
        keepWindowAbove(true);
    }

    m_btnStick->setIcon(QIcon::fromTheme(m_isTop ? "ukui-unfixed-symbolic" : "ukui-fixed-symbolic"));
    m_btnStick->setToolTip(m_isTop ? tr("unfixed") : tr("fixed"));
}

void CMainWnd::showSettingPage()
{
    m_settingPage->show();

    int curWinMode = m_msgPane->getCurWinMode();
    // 侧边模式下，在主屏居中显示；窗口模式下，在窗口居中显示
    if (curWinMode == 2){
       QScreen *screen = QApplication::primaryScreen();
       int screenWidth = screen->size().width();
       int screenHeight = screen->size().height();
       int widgetWidth = m_settingPage->width();
       int widgetHeight = m_settingPage->height();
       int x = (screenWidth - widgetWidth) / 2;
       int y = (screenHeight - widgetHeight) / 2;
       m_settingPage->move(x, y);
    } else {
       int x = this->x() + (this->width() - m_settingPage->width()) / 2;
       int y = this->y() + (this->height() - m_settingPage->height()) / 2;
       m_settingPage->move(x, y);
    }

    if (!m_settingPage->isActiveWindow()) {
        KyInfo() << "m_settingPage isActiveWindow false";
        KWindowSystem::forceActiveWindow(m_settingPage->winId());
    }
}

void CMainWnd::initShortcut()
{
    //设置划词快捷键
    if(m_actionShowScribeWord){
        KGlobalAccel::self()->removeAllShortcuts(m_actionShowScribeWord);
        delete m_actionShowScribeWord;
    }
    m_actionShowScribeWord = new QAction(this);
    m_actionShowScribeWord->setObjectName("Action showScribeWord");
    //这两行必须写，否则注册快捷键的模块名为中文，会导致快捷键注册失败
    m_actionShowScribeWord->setProperty("componentName", "kylin-aiassistant");
    m_actionShowScribeWord->setProperty("componentDisplayName", "AI aiassistant");

    //移除之前需要set一次,估计是bug
    KGlobalAccel::self()->setShortcut(m_actionShowScribeWord, QList<QKeySequence>{Qt::ALT+ Qt::META + Qt::Key_C});
    KGlobalAccel::self()->removeAllShortcuts(m_actionShowScribeWord);

    connect(m_actionShowScribeWord, &QAction::triggered, this, &CMainWnd::onShowScribeWord);
    KGlobalAccel::self()->setShortcut(m_actionShowScribeWord, QList<QKeySequence>{Qt::ALT+ Qt::META + Qt::Key_C});

    //设置助手显示弹窗快捷键
    if(m_actionShowView){
        KGlobalAccel::self()->removeAllShortcuts(m_actionShowView);
        delete m_actionShowView;
    }
    m_actionShowView = new QAction(this);
    m_actionShowView->setObjectName("Action showView");
    //这两行必须写，否则注册快捷键的模块名为中文，会导致快捷键注册失败
    m_actionShowView->setProperty("componentName", "kylin-aiassistant");
    m_actionShowView->setProperty("componentDisplayName", "AI aiassistant");

    //移除之前需要set一次,估计是bug
    KGlobalAccel::self()->setShortcut(m_actionShowView, QList<QKeySequence>{Qt::META + Qt::Key_C});
    KGlobalAccel::self()->removeAllShortcuts(m_actionShowView);

    //connect(m_actionShowView, &QAction::triggered, this, &CMainWnd::showOrHideWindow);
    //KGlobalAccel::self()->setShortcut(m_actionShowView, QList<QKeySequence>{Qt::META + Qt::Key_C});

}

QString CMainWnd::getAiAssistantVersion()
{
#ifdef BUILD_KAIMING
    return qgetenv("APP_VERSION");
#else
    FILE *pp = NULL;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    char *q = NULL;
    QString version = tr("none");

    pp = popen("dpkg -l kylin-aiassistant", "r");
    if(NULL == pp)
        return version;

    while((read = getline(&line, &len, pp)) != -1){
        q = strrchr(line, '\n');
        *q = '\0';

        QString content = line;
        QStringList list = content.split(" ");

        list.removeAll("");

        if (list.size() >= 3)
            version = list.at(2);
    }

    free(line);
    pclose(pp);
    return version;
#endif
}

void CMainWnd::closeOrHidden()
{
    bool isHideTray = g_configManager->getConfigValue("is-hide-tray").toBool();
    KyInfo() << "closeOrHidden====isHideTray:" << isHideTray;
    if(isHideTray){
        this->hide();
    } else {
        this->close();
    }

    return;
}

void CMainWnd::initLoadingIcon()
{
    m_loadingIcon = new QLabel(this);
    QIcon icon = QIcon::fromTheme("kylin-ai-assistant");
    QPixmap pixmap(icon.pixmap(icon.actualSize(QSize(64, 64))));
    m_loadingIcon->setPixmap(pixmap);
    m_loadingIcon->setAlignment(Qt::AlignCenter);
    m_loadingIcon->setScaledContents(true);
    m_loadingIcon->setFixedSize(pixmap.size());
    m_loadingIcon->move((width() - pixmap.width()) / 2 ,
                        (height() - pixmap.height()) / 2);

}

void CMainWnd::checkTheme()
{
    if(QGSettings::isSchemaInstalled("org.ukui.style"))
    {
        themeData = new QGSettings("org.ukui.style");

        if(themeData->get("style-name").toString() == "ukui-dark" || themeData->get("style-name").toString() == "ukui-black")
        {
            Globals::themeColor = 1;
            Q_EMIT sigThemeChanged();
            // changeDarkTheme();
        }
        else
        {
            Globals::themeColor = 0;
            Q_EMIT sigThemeChanged();
            // changeLightTheme();
        }

        Globals::fontSize = themeData->get(UKUI_FONT_SIZE).toString().toFloat();

        connect(themeData, &QGSettings::changed, this, [=](const QString &key) {
            if(key == "styleName")
            {
                if((themeData->get("style-name").toString() == "ukui-dark" || themeData->get("style-name").toString() == "ukui-black"))
                {
                    if(Globals::themeColor != 1)
                    {
                        Globals::themeColor = 1;
                        Q_EMIT sigThemeChanged();
                        // changeDarkTheme();
                    }
                }
                else
                {
                    if(Globals::themeColor != 0)
                    {
                        Globals::themeColor = 0;
                        Q_EMIT sigThemeChanged();
                        // changeLightTheme();
                    }
                }
            }
            else if(key == UKUI_FONT_SIZE)
            {
                //获取字号的值
                int fontSizeKey = themeData->get(UKUI_FONT_SIZE).toString().toFloat();
                //发送改变信号
                if(fontSizeKey > 0)
                {
                    Globals::fontSize = fontSizeKey;
                    Q_EMIT Globals::getinstance()->fontsizeChanged(fontSizeKey);
                }
            }
        });
    }
}

void CMainWnd::keepWindowAbove(bool needTokeepAbove)
{
    qInfo() << "needTokeepAbove " << needTokeepAbove;

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper::States states;
    states |= UkuiWindowHelper::State::Minimizable;
    states |= UkuiWindowHelper::State::Maximizable;
    states |= UkuiWindowHelper::State::Closeable;
    states |= UkuiWindowHelper::State::Fullscreenable;

    states |= UkuiWindowHelper::State::Resizable;
    states |= UkuiWindowHelper::State::Focusable;
    states |= UkuiWindowHelper::State::Activatable;

    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    qInfo() << "winMode " << winMode;
    if (winMode == 3){
        states |= UkuiWindowHelper::State::Movable;
    }

    if (needTokeepAbove) {
        states |= UkuiWindowHelper::State::KeepAbove;

    }

    m_ukuiWindowHelper->setWindowState(states);
#else
    qInfo() << "m_window_id " << m_window_id;
    kdk::WindowManager::keepWindowAbove(m_window_id);
#endif

    return;
}

void CMainWnd::setMovable(bool isMovable)
{
    qInfo() << "isMovable " << isMovable;

#ifdef UKUI_WINDOWHELPER_SUPPORT
    UkuiWindowHelper::States states;
    states |= UkuiWindowHelper::State::Minimizable;
    states |= UkuiWindowHelper::State::Maximizable;
    states |= UkuiWindowHelper::State::Closeable;
    states |= UkuiWindowHelper::State::Fullscreenable;
    states |= UkuiWindowHelper::State::Resizable;
    states |= UkuiWindowHelper::State::Focusable;
    states |= UkuiWindowHelper::State::Activatable;

    if (isMovable) {
        states |= UkuiWindowHelper::State::Movable;
    }

    if (m_isTop) {
        states |= UkuiWindowHelper::State::KeepAbove;

    }

    m_ukuiWindowHelper->setWindowState(states);
#else
    this->topLevelWidget()->setProperty("useStyleWindowManager", isMovable);
#endif

    return;
}

///
/// \brief CMainWnd::initTitleBar 初始化标题栏组件
///
void CMainWnd::initTitleBar()
{
    m_leftBtnWidget = new QWidget(this);
    m_leftBtnWidget->setAccessibleName("kylin-aiassistant_QWidget_m_leftBtnWidget");

    m_btnSideBar = new CPushButtonEx(this);
    m_btnSideBar->setAccessibleName("kylin-aiassistant_CPushButtonEx_m_btnSideBar");

    m_btnBack = new QPushButton(this);
    m_btnBack->setAccessibleName("kylin-aiassistant_QPushButton_m_btnBack");

    m_btnStick = new QPushButton(this);
    m_btnStick->setAccessibleName("kylin-aiassistant_QPushButton_m_btnStick");
    connect(m_btnStick, &QPushButton::clicked, this, &CMainWnd::slotToTop);

    // 按照设计稿设计，窗口按钮大小为 32x32
    m_btnSideBar->setFixedSize(32, 32);
    m_btnSideBar->setIcon(QIcon(QString(":/icon/icon/window.svg")));
    m_btnSideBar->setIconSize(QSize(16, 16));
    m_btnSideBar->setProperty("isWindowButton", 0x1);
    m_btnSideBar->setProperty("useIconHighlightEffect", 0x2);
    m_btnSideBar->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnSideBar->setFlat(true);
    m_btnSideBar->setToolTip(tr("sidebar"));

    m_btnBack->setFixedSize(32, 32);
    m_btnBack->setIcon(QIcon(QString(":/icon/icon/back.svg")));
    m_btnBack->setIconSize(QSize(16, 16));
    m_btnBack->setProperty("isWindowButton", 0x1);
    m_btnBack->setProperty("useIconHighlightEffect", 0x2);
    m_btnBack->setProperty("windowMode", WINDOW_MODE_NORMAL);
    m_btnBack->setFlat(true);
    m_btnBack->setVisible(false);
    m_btnBack->setToolTip(tr("Back to homepage"));


    QHBoxLayout *leftBtnLayout = new QHBoxLayout;
    leftBtnLayout->setContentsMargins(6, 0, 0, 0);
    leftBtnLayout->addWidget(m_btnSideBar);
    leftBtnLayout->addWidget(m_btnBack);
    leftBtnLayout->setSpacing(0);
    leftBtnLayout->addSpacerItem(new QSpacerItem(20,20,QSizePolicy::Expanding,QSizePolicy::Minimum));
    m_leftBtnWidget->setFixedSize(70, 32);
    m_leftBtnWidget->setLayout(leftBtnLayout);

    // 按照设计稿设计，置顶按钮大小为 32x32
    m_btnStick->setFixedSize(32, 32);
    m_btnStick->setProperty("isWindowButton", 0x1);
    m_btnStick->setProperty("useIconHighlightEffect", 0x2);
    m_btnStick->setFlat(true);
    m_btnStick->setIcon(QIcon::fromTheme("ukui-fixed-symbolic"));
    m_btnStick->setToolTip(tr("fixed"));
    m_btnStick->setFocusPolicy(Qt::NoFocus);
    m_btnStick->setVisible(true);

    KWindowButtonBar *button_bar = windowButtonBar();
    ((QHBoxLayout *)button_bar->layout())->insertWidget(0, m_leftBtnWidget);
    QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    ((QHBoxLayout *)button_bar->layout())->insertSpacerItem(1, spacer);
    ((QHBoxLayout *)button_bar->layout())->insertWidget(3, m_btnStick);
    button_bar->maximumButton()->hide();
    button_bar->minimumButton()->hide();

    KIconBar *iconbar = iconBar();
    iconbar->setFixedWidth(200);
    iconbar->setIcon(QIcon::fromTheme("kylin-ai-assistant"));
    iconbar->setWidgetName(tr("kylin-aiassistant"));
    iconbar->setVisible(false);
}

///
/// \brief CMainWnd::initComponent 初始化UI组件
///
void CMainWnd::initComponent()
{
    m_loadingIcon->setVisible(false);
    createAllChildWnd();
    initCtrl();
    initTopping(); // 初始化置顶
    initSolts();
    initLayout();

    initScribeWords();
    initScribeWordsSetting();
    initShortcut();
    initPosition();

    checkTheme();
}

void CMainWnd::initWindowMode()
{
    // 解决窗口模式切换初始化加载出错问题
    int winMode = g_configManager->getConfigValue("win-mode").toInt();
    if (winMode == 2) {
        switchToSideMode();
    } else if (winMode == 3) {
        switchToWindowMode();
    } else {
        switchToSideMode();
    }
}

void CMainWnd::aboutToQuit()
{
    qInfo() << "aboutToQuit";
    if(!m_msgPane->getIsReplying())  {
        return;
    }
    m_msgPane->pushMsg("replyEnd", true);
    return;
}

void CMainWnd::handleSendFile()
{
    if (m_peonyPluginFilePath.isEmpty()) {
        return;
    }

    QFileInfo fileInfo(m_peonyPluginFilePath);
    if (g_supportPicFormats.contains(fileInfo.suffix().toLower())) {
        m_msgPane->onShowImage(m_peonyPluginFilePath, 1);
    } else if (g_supportDocFormats.contains(fileInfo.suffix().toLower())) {
        m_msgPane->onShowDocument(m_peonyPluginFilePath);
    }

    return;
}
