#ifndef CMSGPANE_H
#define CMSGPANE_H

#include "reader.h"
#include "recorder.h"
#include "chatdatabase.h"
#include "systemchat.h"
#include "modelitemlistmodel.h"
#include <kysdk/diagnosetest/libkydatacollect.h>
#include <unistd.h>
#include <string>
#include <cmark.h>
#include <iostream>


#include <QAction>
#include <QApplication>
#include <QBuffer>
#include <QByteArray>
#include <QDBusUnixFileDescriptor>
#include <QDBusInterface>
#include <QDBusObjectPath>
#include <QDBusReply>
#include <QDateTime>
#include <QDebug>
#include <QDesktopWidget>
#include <QDir>
#include <QImage>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QLabel>
#include <QMenu>
#include <QMenuBar>
#include <QPushButton>
#include <QSystemTrayIcon>
#include <QTextEdit>
#include <QTimer>
#include <QToolButton>
#include <QWidget>
#include <QProcess>
#include <QPrinter>
#include <QImageWriter>

class CPushButtonEx;
class Reader;
class Recorder;
class PhotoViewerPlugin;
#define MAXIMAGESIZE 50 * 1024 * 1024

using namespace kyai::config::model;


class SystemChat;
enum WindowMode
{
    WINDOW_MODE_NORMAL = 0,
    WINDOW_MODE_OCCUPIED =1,
    WINDOW_MODE_SIDEMODE =2,
    WINDOW_MODE_WINDOWMODE=3,
};
enum ActiveModule{
    MODULE_PLUGIN = 0,
    MODULE_CHAT = 1
};

class CMsgPane : public QObject
{
    Q_OBJECT
public:
    explicit CMsgPane();
    //报错消息头处理
    void errorMessageToJs(QString msgHead, QString modelMsg, QString colorMsg, QString errorMsg);
    void errorMessageToJsNoModel(QString msgHead, QString modelMsg, QString colorMsg, QString errorMsg);
    void systemMessageToJs(QString msgHead, QString modelMsg, QString colorMsg, QString systemName, QString systemIcon, QString msg);
    void clearJsonMessage();

    WindowMode m_windowMode;
    ActiveModule m_activeModule = ActiveModule::MODULE_CHAT;
    void pushMsg(QString func);
    void pushMsg(QString func, QVariant arg1);
    void pushMsg(QString func, QString jsonMsgHeadToWeb, QString msg);
    bool getIsEnd();
    void showTip(QString tipMessage);
    bool getIsChatReady(){return m_isChatReady;}

public slots:
    // 切换模型
    void onSetCloudModel(AiCapability capability, QString modelName);
    bool isCurrentModelAvailable();
    //返回主页
    void onBackBtnClicked();
    void onSwitchToPlugin(QString page);
    //消息
    void onClearContext();
    QString onSendMsg(const QString &jsonMsgHead, const QString &msg);
    void onRecvMsg(QString reasoningContentMsg, QString msg, bool is_reasoning_end, bool is_end, int index, int errorCode, QString model = "", QString feedbackURL = "");
    void onAudioRecvMsg(QString msg, bool is_end, int index, int errorCode, QString model);         //处理语音类问题报错
    void onRecvTool(QString msg, QMap<int, QString> imageToolMap, QString imagePath, int errorCode, QString model, QString feedbackURL);
    void onSaveMessageList();
    void onLoadMessageList();
    void onChangedIsReplyingStatus(bool isReplying);
    //图像
    void onSelectFile(int typeNum);
    void onShowAddFileMenu();
    void onShowImage(const QString &imagePath, int counts);
//    void onSendImage(const QString &imagePath);
    QString onPictureOperateClick(int toolId, const QString &imagePath);
    void onImageDragIn(bool dragin);
    void onShowErrorMoreImage();
    void onShowErrorSizeImage();
    void onShowErrorFormatImage();
    void updateToShowPic(QString imageData, QString errorMessage); // 更新图片处理返回的图片
    void updateToShowOperatePic(QString imageData, QString errorMessage); // 更新图像处理返回的图片
    void sigPictureAutoSpeak(); //语音文生图后触发自动朗读
    //文档
    void onShowDocument(const QString &filePath);
    void onShowErrorFormatFile();
    void onShowErrorFormat();
    //文生图
//    void updateToShowAIPic(VisionImageData *imageData, QString errorMessage); // 更新AI文生图的图片
    void onDownloadImage(const QString &base64Image); // 下载图片
    void onSaveHTML2PDF(const QString &base64Image);
    //系统助手-信息来源
    void updateToShowSource(QMap<int, QString> infoSourceMap); // 更新系统助手信息来源
    void onSelectInfoSource(int toolId); // 跳转到信息来源
    void onChatTimeout();
    void restartTimeoutTimer();
    //埋点数据
    void onSendDataCollect(const QString &eventCode, const QString &pageName);
    //会话
    void saveDialog();
    void clearDialog();
    void userAccountsChanged();
    void loadPlugin(QString pluginHtmlFile);
    void onAddToSchedule(int operatorId, QString schedule_date, QString msg, QString model, QString feedbackURL);    //添加到日历
    void openSchedule(QString schedule_date);                       //通过AI SDK打开日历
    //功能-语音输入
    void onSendAudio();
    void onStopAudio();
    void onCancelAudio();
    void onStartTimer();        //打开30s定时器
    void onSpeechModeChanged(int speechMode);    // 更新语音状态
    //功能-语音朗读
    void onStartRead(const QString &msg, int index);
    void onPauseRead();
    void onContinueRead(int index);
    void onReadEnd(int index);
    //语音听写
    void onClearDictation();
    //复制成功
    void onCopySuccess();
    void onCopyText(const QString &text);
    void onCopyImage(const QString &base64Image);
    //点赞点踩
    void onLikeAction();
    //新建对话-提示对话进行中
    void onContinueDialog();
    void onTipsContinueDialog();

    void onStopReply();
    //清除所有Session
    void onCloseAllSession();
    void xdgOpen(QString path);
    void xdgOpenForImageOperate(QString base64Image,int operatorId, QString imagePath);
    void saveToDatabase(int msgInex, QString message);  //保存消息进数据库
    void updateLastMessage(int msgInex, QString message); // 更新最后一条数据的message到数据库
    void updateFeedbackDatabase(int msgInex, QString message);
    void loadHistory();
    void loadHistoryBySessionId(QString sessionId);

    void getPluginList();
    void getDialogueList();
    void modifyDialogueList(const QVariantList &strings);
    void initDeleteLayout(const QVariantList &strings);
    void closeSession();
    void deleteSessionList(const QVariantList &strings);

    int getCurWinMode(){return m_windowMode;}
    QString convertMarkDownToHtml(const QString &markDown);
    ActiveModule getCurrentActiveModule(){return m_activeModule;}
    void updateCurrentActiveModule(const int pageNumber);
    void initCurrentUser();

    //文档处理
    void openDocument(const QString &documentPath); // 打开文档
    bool isSupportDocumentQA(); //返回是否支持文档问答
    bool isSupportHtml2Docx(); //返回是否支持周报html格式转docx格式

    //图片处理
    bool isSupportImageProcessing(); //返回是否支持图片问答

    int getCurrentSessionId();

    void activateMainWindow();  // 触发信号
    int getShowPage();
    void updateDialogueListSessionId();
    void onStopSpeak(); //停止朗读
    void openUkuiControlCenter();
    void handleInputDeviceChanged();
    void onStartReplyingToChat();
    void onChatInited();
    ///
    /// \brief initNLPModelList  初始化NLP模型可用列表，也可用于刷新
    ///
    void initNLPModelList();

    ///
    /// \brief getNLPCurModel 获取当前选择的NLP模型，以config为准，存在runtime和config不一致的情况
    /// \return 模型名
    ///
    QString getNLPCurModel();

    ///
    /// \brief setNLPModel 设置NLP模型，下次对话时生效。
    /// \param name 模型名
    ///
    void setNLPModel(QString name);

    ///
    /// \brief stopLoadTimer 30s加载计时停止
    ///
    void stopLoadTimer();

    ///
    /// \brief setPopupExist 设置是否存在popup弹出
    /// \param isExist 存在popup
    ///
    void setPopupExist(bool isExist);

    ///
    /// \brief getPopupExist 获取是否存在popup弹出
    ///
    bool getPopupExist();

public:
    int m_operatorId = -1; // 图像处理操作id

    bool getIsReplying();
private:
    void createAllChildWnd();
    void initSolts();
    void initChatOperator();
    void initPluginList();
    void initCommandList();
    void initLoadingTimer();
    void initCurrentUserName();
    void initCurrentUserIcon();


    void saveDialogToFile(const QString &dialogJsonString);
    void saveMessageToFile(const QString &msgJsonString);
    void commitData(QSessionManager &manager);

    QString getBase64FromImagePath(const QString &imagePath); // 从图片路径获取到Base64编码
    QString getDefaultFace();
    bool isCommunity();
    void initDefaultUserIcon();
    QString markdownToHtml(const std::string& markdown);
    bool checkChatModel(int errorCode);
    QTimer *m_loadTimer = nullptr;
    bool isPopupExist = false;

private slots:
    void updateBubble();

signals:
    void sigSetup();
    void sigSaveDialog(QString filePath);
    void sigLoadMyMessageBox(const QVariantList &strings);
    void addMsg(QString jsonMsgHead, QString msg);
    void addRecvMsg(QString jsonMsgHead, QString msg);
    void updateMsg(QString jsonMsgHead, QString msg);
    void updateReasoningMsg(QString jsonMsgHead, QString msg);
    void addRecvSources(QString jsonMsgHead);
    void appendRecvTool(QString jsonMsgHead);
    void replyEnd(bool isEnd);
    void replyingChanged(bool replying);
    void insertImage(QString base64EncodedImage, int operatorId, QString imagePath);    //向前端發送文生圖生成的圖片
    void sigCancelGenerateImage();
    void insertOperateImage(QString base64EncodedImage, int operatorId, QString imagePath); //图像处理向前端发送生成的图片
    void updateOperateRefresh(); //图像处理更新重新回答为不可用
    void setReadEnd(int index);
    void sendImage(QString imagePath, QString base64Image);
    void setReplyOptions(const QString imagePath);
    void recvImage(const QString scheJsonMsgHeadToWeb, const QString blackAndWhiteImagePath, const QString base64Image);
    void sigChangeIsStartNetworkError(bool IsStartNetworkError);
    void sigHasNoModel(const QString errorStr);//未配置模型处理信号
    void contextCleared();
    void loadConversation(QStringList list);
    //侧边栏模式控制前端显示页面
    //0显示全部 1显示主页面 2显示侧边栏 4窗口模式下显示主界面
    void showPage(int num);    void showPluginPage(int num, QString pluginName);//侧边栏模式切换插件页面
    void showWindowPage(int num);   //窗口模式切换页面
    void showWindowPluginPage(int num, QString pluginName); //窗口模式切换插件页面
    void changeToSideMode(int width, int height);
    void changeToWinMode(int height);
    void changeWinModeToChat(int num);
    void loadDialogueList(QStringList list);
    void loadPluginList(QStringList list);
    void deleteDialogueList(QStringList deleteList);
    void changeCurrentUserName(QString name);
    void changeCurrentUserIcon(QString name);
    void copyToClipboard(QString text);     //添加文字到剪切板
    void copySuccess();
    void copyImageToClipboard();
    void tipsContinueDialog();
    void addImagePreview(QString imagePath, QString base64Image);
    void addDocumentPreview(QString filePath, QString icon, QString fileName, QString fileSize);
    void saveToPDF();
    void addReportPath(QString path);
    void showSettingPage();
    void modifyDialogueListFlag(QString sessionID);
    void sigSaveAs(const QString &base64Image); //图片另存为打开filedialog
    void sigOpenFile(int type);
    void sigShowAddFileMenu();
    void sigAddFileMenuHide();

    void sigBtnClicked(const int activeModule);
    void saveLastMsgToDatabase();       //将listmodel最后一条消息存入数据库
    void cancelSendAudio(); //取消语音发送
    void updateCurrentStartTimer();
    void triggerAutoRead(QString msg);
    void clearListModel();
    void moveScrollBar();  //将前端滚动条移动到最新位置
    void changeSessionId(int sessionId);  //发送前端当前的sessionId
    void activateMainWindowSignal();  // 定义一个信号
    void keyReturnPressed();//发送按下回车键信号
    void updateDialogueList();
    void cancelVoiceStopReplying();//取消语音发送
    void sigSendTmpMsgToQML(const QString str); //向前端发送语音识别中间结果
    void sigSendMsgToQML(const QString str);    //向前端发送语音识别修正后结果
    void sigResetPreIndex();
    void sigLikeAction();
    void startReplyingToChat(bool isReplying);
    void sendFocusChanged();
    void chatInitCompleted();
    void sigNlpModelInitCompleted();
    void showTipMessage(QString tipMessage);
    void sigClearTextArea();     // 清空输入区域
    void timeoutTimerTriggered();
    void timeoutTimerRestarted();

private:
    Reader *m_reader = nullptr;
    Recorder *m_recorder = nullptr;

    CommandTemplateList *m_commandListModel = nullptr;

    CPushButtonEx *m_btnMore = nullptr;
    CPushButtonEx *m_btnVoice = nullptr;
    QLabel *m_labSeparatorLine = nullptr;
    QAction *confAction = nullptr;
    //NLP语言模型
    SystemChat *m_chat = nullptr;
    bool m_isChatReady = false;   //标记SDK服务是否初始化完成

    //文字发送的消息
    QString send_message;
    //语音发送消息到前端
    QString speech_send_message;
    int bubble_show_speech_count;
    uint loading_speech_dot_index;
    QTimer *speech_bubble_update_timer = nullptr;
    bool new_reply = true;                  //标记是否为新回答
    bool m_is_reasoning_end = true; // 标记思考过程是否结束
    QString recv_message;
    QString recv_reasoning_message; // 思考过程接收消息
    QString msgHead;                        //消息头
    int promptId = -1;                      //提示词ID
    QString promptIconPath;                        //提示词icon
    bool speechFlag;
    QJsonObject jsonObjToWeb;
    QString m_defaultUserIcon;
    ChatDatabase * m_database = nullptr;    //数据库
    QStringList m_pluginList;

    QString imagePath;
    QString imageSrc;

    QString documentPath;
    QString documentIcon;
    QString documentName;
    QString documentSize;
    //待办
    QString m_todolist;
    int toolId = -1;

    // 语音四种状态，对应qml speechMode: 0 点击说话（启动状态）1 点击说话（禁用状态）2 完成说话（启用状态）3 识别中...（禁用状态）
    int speechMode = 0;

    //更新isreplying
    bool  m_isReplying = false;
};

#endif // CMSGPANE_H
