#include "voicechatanswer.h"

bool is_voice_reply_end = true;

static VoiceChatAnswer *g_voiceChatAnswer = nullptr;

/**
 * @brief voiceChatCallback
 *          对话回调函数，用于接收语音通话的回答文字
 * @param text_data
 */
static void voiceChatCallback(const std::string text_data)
{
    VoiceChatAnswer *voiceThread = VoiceChatAnswer::getPtr();
    const char *result = text_data.data();

    //处理JSON数据
    QJsonParseError jsonError;
    QJsonDocument doc = QJsonDocument::fromJson(result, &jsonError);
    if(jsonError.error != QJsonParseError::NoError)
    {
        KyInfo() << "JSON parsing error: " << jsonError.errorString();
        return;
    }

    QJsonObject obj = doc.object();

    int errorCode = obj.value("error_code").toInt();
    QString errorMsg = obj.value("error_message").toString();
    QString messageType = obj.value("message_type").toString();
    QString model = obj.value("model").toString();

    QJsonArray contentArray = obj["content"].toArray();
    QJsonArray infoSourceArray;
    QMap<int, QString> imageToolMap;
    QMap<int, QString> infoSourceMap;
    QString fileData = "";



    //处理报错
    if(errorCode != 0)
    {
        KyInfo() << "当前语音对话错误，错误码为"<< errorCode;
        //处理通话异常
        voiceThread->parseAndSendErrorMsg(errorCode);
        // 回答错误后，本次回答已经结束，重置首次回答标志位
        voiceThread->m_isFirstReply = true;
        return;
    }

    if(messageType == "chat")
    {

        // 遍历content数组
        for(const QJsonValue &value: contentArray)
        {
            // 假设每个元素都是一个对象
            QJsonObject itemObject = value.toObject();

            // 检查type是否为"text"
            if(itemObject["type"].toString() == "text")
            {
                // 获取text子对象
                QJsonObject textObject = itemObject["text"].toObject();
                voiceThread->is_end = textObject["is_end"].toBool();
                voiceThread->result_msg = textObject["result"].toString();
                voiceThread->result_index = obj.value("sentence_id").toInt();
                voiceThread->reasoningContentMsg = textObject["reasoning_content"].toString();//深度思考内容
                if(voiceThread->reasoningContentMsg == ""){
                    voiceThread->is_reasoning_end = true;
                }else{
                    voiceThread->is_reasoning_end = false;
                }
                // 回答结束后将首次回答标志设置为true
                if(voiceThread->is_end) {
                    voiceThread->m_isFirstReply = true;
                }

            }

            if(itemObject["type"].toString() == "file_data")
            {
                fileData = itemObject["file_data"].toString();
            }
        }

        // 检查是否包含information_sources字段
        if(!obj.contains("information_sources"))
        {
//            KyInfo() << "No information sources";
        }
        else if(obj.value("information_sources").isNull())
        {
//            KyInfo() << "information_sources is null";
        }
        else
        {
            infoSourceArray = obj["information_sources"].toArray();
        }

        // 遍历information-sources数组
        for(const QJsonValue &value: infoSourceArray)
        {
            QJsonObject itemObject = value.toObject();
            // 检查是否包含text和tool_id
            if(itemObject.contains("text") && itemObject.contains("tool_id"))
            {
                int toolId = itemObject["tool_id"].toInt();
                QString sourceName = itemObject["text"].toString();
                infoSourceMap.insert(toolId, sourceName);
            }

            for(auto i = infoSourceMap.begin(); i != infoSourceMap.end(); ++i)
            {
                KyInfo() << "information-sources: "
                         << "toolid:" << i.key() << "sourceName:" << i.value();
            }
        }

        is_voice_reply_end = voiceThread->is_end;
        voiceThread->m_isAnswing = !voiceThread->is_end;

        switch (voiceThread->target) {
        case TartgetType::RECVMSG:
            //首次开始回复时，需要发送信号给前端，将状态设置为回答中
            if(voiceThread->m_isFirstReply == true) {
                voiceThread->m_isFirstReply = false;
                emit voiceThread->sigBeginReplying();
            }

            //如果正在执行打断，则发送收到停止信号后，立马就返回前端
            if(voiceThread->m_isInterrupt && voiceThread->is_end) {

                KyInfo() << "当前符合正在打断文本回复状态，发送信号，通知对话模块打断已成功";
                emit voiceThread->sigInterruptSuessful();
                voiceThread->setInterrupt(false);

            }

            //非打断模式下，如果已经is_end=true,证明回答结束了
            if(voiceThread->is_end)
            {
               KyInfo() << "回答已经结束，将需要回答和回答中标志设为false";
               voiceThread->m_isAnswing = false;
               voiceThread->m_isNeedAnswering = false;
            }


            //发送正常消息
            QJsonObject msg;
            msg["msgType"] = "recvAnswerMsg";

            QJsonObject msgBody;
            msgBody["isEnd"] = voiceThread->is_end;
            msgBody["recvMsg"] = voiceThread->result_msg;
            msgBody["reasonMessage"] = voiceThread->reasoningContentMsg;
            msgBody["modelMsg"] = model;
            msgBody["colorMsg"] = "black";
            msgBody["sentByUser"] = false;
            msgBody["errorCode"] = errorCode;
            msg["msgBody"] = msgBody;

            Q_EMIT voiceThread->sigReceiveChatAnswerMessage(QString::fromUtf8(QJsonDocument(msg).toJson()));
            // 获取当前时间并格式化
            //QString timeStamp = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");

            break;

    }

    }

    return;
}

VoiceChatAnswer::VoiceChatAnswer(QObject *parent)
  : QObject{parent}
  , m_isFirstReply(true)
{
    initConnect();
    m_voiceThreadSessionID = ConfigManager::getInstance()->getConfigValue("voice-id").toInt();

}

VoiceChatAnswer::~VoiceChatAnswer()
{

}

VoiceChatAnswer *VoiceChatAnswer::getPtr()
{
    if (g_voiceChatAnswer == nullptr) {
        g_voiceChatAnswer = new VoiceChatAnswer;
    }

    return g_voiceChatAnswer;
}

void VoiceChatAnswer::initConnect()
{
    return;
}

bool VoiceChatAnswer::initChatSession()
{
    m_voiceThreadOsassistant = new kyai::assistant::OsAssistant();
    m_voiceThreadOsassistant->setChatAsyncCallback(voiceChatCallback);
    KyInfo() << "*** start initVoiceThread m_osassistant->init()";
    Error error = m_voiceThreadOsassistant->init();
    KyInfo() << "*** end initVoiceThread m_osassistant->init()";
    //SDK ErrorCode 内部定义冲突
    if(error.code != kyai::assistant::ErrorCode::Ok)
    {
        KyInfo() << "init VoiceThread failed";

        return false;
    }

    return true;
}

void VoiceChatAnswer::stopChat()
{
    m_voiceThreadOsassistant->stopChat();
    m_isNeedAnswering = false;

    return;
}

void VoiceChatAnswer::stopReply()
{
    m_voiceThreadOsassistant->stopChat();
    m_isNeedAnswering = false;
    KyInfo() << "结束语音对话回复";

    return;
}

void VoiceChatAnswer::interruptReply()
{
    m_voiceThreadOsassistant->stopChat();
    m_isNeedAnswering = false;
    KyInfo() << "打断语音对话回复";

    return;
}

void VoiceChatAnswer::clearContext()
{
    m_voiceThreadOsassistant->clearContext();

    return;
}

void VoiceChatAnswer::sendQuestion(QString text, QString filePath)
{
    //创建顶层对象
    QJsonObject jsonObject;
    //设置message_type字段
    jsonObject["message_type"] = "chat";
    //创建content数组
    QJsonArray contentArray;

    //文本消息
    if(text.length() > 0)
    {
        QJsonObject textMessage;
        textMessage["type"] = "text";
        textMessage["text"] = text;
        contentArray.append(textMessage);
    }

    // 将content数组设置到顶层对象
    jsonObject["content"] = contentArray;

    // 设置联网搜索和深度思考
    jsonObject["web_search"] = m_isWebSearch;
    jsonObject["enable_thinking"] = m_isDeepThinking;

    QJsonDocument jsonDoc(jsonObject);
    KyInfo() << "m_voiceThreadOsassistant sendQuestion chatAsync.";
    m_voiceThreadOsassistant->chatAsync(jsonDoc.toJson().toStdString());
    m_isAnswing = true;
    m_isNeedAnswering = true;
    m_isFirstReply = true;

    return;
}

void VoiceChatAnswer::setSession(int voiceSessionID)
{
    m_voiceThreadSessionID = voiceSessionID;

    return;
}

void VoiceChatAnswer::closeSession()
{
    m_voiceThreadOsassistant->stopChat();
    m_voiceThreadOsassistant->clearContext();
}

bool VoiceChatAnswer::getCurrentAnswerStatus()
{

    bool status = m_isAnswing || m_isNeedAnswering;

    KyInfo() << "当前文本回答状态:" << status <<"m_isAnswing:"<<m_isAnswing<<"m_isNeedAnswering:"<<m_isNeedAnswering;

    return status;
}

void VoiceChatAnswer::setInterrupt(bool isInterrupt)
{
    m_isInterrupt = isInterrupt;
}

bool VoiceChatAnswer::getInterruptStatue()
{
    return m_isInterrupt;
}

void VoiceChatAnswer::parseAndSendErrorMsg(const int errorCode)
{
    QString errorMsg = "";

    // 检查错误信息是否等于模型未配置
    kyai::assistant::ErrorCode error = static_cast<kyai::assistant::ErrorCode>(errorCode);
    // 模型未配置
    if(error == kyai::assistant::ErrorCode::NlpModelNotFound) {
       errorMsg = tr("<span style=\"color:red\">There are currently no available large language model available.</span> \n\n Configuration steps: \n\n 1. Go to the **System Settings > AI Module Management > Model Configuration** page to add a \"cloud model\", a \"local model\" or a \"optional model\". \n 2. If the model configuration is already completed, please confirm whether the model is enabled. \n\n Note: Running a local model may consume significant device resources. Please ensure your device meets the performance requirements.");

       QJsonObject msg;
       msg["msgType"] = "recvAnswerMsg";

       QJsonObject msgBody;
       msgBody["isEnd"] = true;
       msgBody["recvMsg"] = errorMsg;
       msgBody["reasonMessage"] = "";
       msgBody["modelMsg"] = "由AI助手生成";
       msgBody["colorMsg"] = "black";
       msgBody["sentByUser"] = false;
       msgBody["errorCode"] = errorCode;
       msg["msgBody"] = msgBody;

       Q_EMIT  sigReceiveChatAnswerMessage(QString::fromUtf8(QJsonDocument(msg).toJson()));

       return;
    }

    // 其他类型报错
    //对于未知错误，展示error_message字段对应的所有值
    errorMsg = Globals::getErrorMsg(errorCode);
    //拼接消息头进行错误信息回复
    QJsonObject msg;
    msg["msgType"] = "recvAnswerMsg";

    QJsonObject msgBody;
    if(static_cast<kyai::assistant::ErrorCode>(errorCode) == kyai::assistant::ErrorCode::FreeAllocatedQuotaExceeded){
        // 拼接红色异常提示和正常黑色提示文字
        errorMsg = "<span style=\"color:red\">" + errorMsg + "</span>"+ "\n\n" + tr("To ensure the normal use of the AI assistant, please go to System Settings > AI Module Management > Model Configuration to configure the model.");
        msgBody["colorMsg"] = "black";
    }else if(static_cast<kyai::assistant::ErrorCode>(errorCode) == kyai::assistant::ErrorCode::LocalNlpModelNotLoaded){
        // 拼接红色异常提示和正常黑色提示文字
        errorMsg = "<span style=\"color:red\">" + errorMsg + "</span>"+ "\n\n" + tr("Configuration steps:\n1. Go to the **System Settings > AI Module Management > Model Configuration** page to add a \"cloud model\", a \"local model\" or a \"optional model\".\n2. If the model configuration is already completed, please confirm whether the model is enabled.\n\nNote: Running a local model may consume significant device resources. Please ensure your device meets the performance requirements.");
        msgBody["colorMsg"] = "black";
    }else {
        msgBody["colorMsg"] = "red";
    }

    msgBody["isEnd"] = true;
    msgBody["recvMsg"] = errorMsg ;
    msgBody["reasonMessage"] = "";
    msgBody["modelMsg"] = "由AI助手生成";
    msgBody["sentByUser"] = false;
    msgBody["errorCode"] = errorCode;
    msg["msgBody"] = msgBody;

    Q_EMIT  sigReceiveChatAnswerMessage(QString::fromUtf8(QJsonDocument(msg).toJson()));

    return;
}

void VoiceChatAnswer::setModel(const QString name)
{
    m_voiceThreadOsassistant->setCurrentNlpModel(name.toStdString());
}

void VoiceChatAnswer::setDeepThinking(bool checked)
{
    m_isDeepThinking = checked;
}

void VoiceChatAnswer::setWebSearch(bool checked)
{
    m_isWebSearch = checked;
}
