#include "chatoperator.h"

#include <QThread>
#include <QTime>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include <QJsonDocument>

#include <ukui-log4qt.h>

#include "global/kaglobal.h"

bool is_reply_end = true;

class ChatOperator::Private
{
public:
    void* session = nullptr;
};

/**
 * @brief chatCallback
 *          聊天结果返回回调函数，数据流式返回
 * @param result
 * @param usr_data
 */
static void chatCallback(const char *result, void *usr_data)
{
    ChatOperator *chatOperator = (ChatOperator*)usr_data;
    QJsonParseError jsonError;
    QJsonDocument doc = QJsonDocument::fromJson(result, &jsonError);
    if (jsonError.error != QJsonParseError::NoError)
    {
        return;
    }

    QJsonObject obj = doc.object();

    bool is_end = obj.value("is_end").toBool();
    QString result_msg = obj.value("result").toString();
    int result_index = obj.value("sentence_id").toInt();

    is_reply_end = is_end;

    if (chatOperator->target == RECVMSG){
        chatOperator->notifyUI(result_msg, is_end, result_index);
    }else{
        emit chatOperator->sigGenerateSummary(result_msg, is_end, result_index);
    }
}

ChatOperator::ChatOperator(QObject *parent)
    : QObject{parent},
      d(std::make_shared<ChatOperator::Private>())
{
    initSession();
    connect(g_gsettings, &QGSettings::changed, [this](QString key){
        if (key == "isNlpSetup")
        {
            if (g_gsettings->get("isNlpSetup").toBool())
                reInitSession();
            else
                closeSession();
        }
    });
}

ChatOperator::~ChatOperator()
{
    if (d->session)
        nlp_destory_session(d->session);
}

bool ChatOperator::reInitSession()
{
    closeSession();
    initSession();
    return true;
}

bool ChatOperator::sendMessage(const QString &message)
{
    QString send_message = message;

    QThread::create([this, send_message](){
        if (nlp_text_chat_async(d->session, send_message.toStdString().c_str()) != NLP_SUCCESS)
        {
            KyInfo() << "send message error";
            emit sigSendMessageError();
        }
    })->start();

    return true;
}

void ChatOperator::notifyUI(const QString &message, bool is_end, int index)
{
    if (is_end) {
        emit sigSessionCompleted();
    }

    emit reply(message, is_end, index);
}

void ChatOperator::setActor(int actorId)
{
    nlp_set_session_actor(d->session, actorId);
}

bool ChatOperator::initModelVendor()
{
    QJsonObject obj;
    obj.insert("apiKey", "0bLvOdqlo1Gzu2jbpf9imTsT");
    obj.insert("secretKey", "H0ThDOxNvTKEbNgyeHyKdw35R6dw3AcE");

    return set_remote_model_config(BAIDU, NLP, QJsonDocument(obj).toJson().toStdString().c_str());
}

bool ChatOperator::initSession()
{
//    QThread::create([this]{
        void *session = nullptr;
        NlpResult ret = nlp_create_session(&session);
        if (ret != NLP_SUCCESS || session == nullptr) {
            KyInfo() << "nlp create session error :" << ret;
            return false;
        }

        ret = nlp_init_session(session);
        if (ret != NLP_SUCCESS) {
            KyInfo() << "nlp init session error :" << ret;
            return false;
        }

        d->session = session;

        nlp_set_result_callback(d->session, chatCallback, this);


//    })->start();
    return true;
}

void ChatOperator::closeSession()
{
    if (d->session)
        nlp_destory_session(d->session);

    d->session = nullptr;
}

void ChatOperator::clearSession()
{
    if (d->session) {
        nlp_clear_context(d->session);
    }

    return;
}

void ChatOperator::stopChat()
{
    if (d->session) {
        //测试stop功能
        if (nlp_stop_chat(d->session) != NLP_SUCCESS)
            KyInfo() << "nlp stop chat error";
    }
    return;
}
