#include "minichatthread.h"
#include "../cmainwnd.h"

static MiniChatThread *g_miniChatThread = nullptr;

MiniChatThread::MiniChatThread(QObject *parent)
    : QThread (parent)
{
    start();
}

MiniChatThread::~MiniChatThread()
{
    if ((mWritingSession == NULL) || (mWritingConfig == NULL)) {
        KyInfo() << "Writing session is not created!";
    } else {
        genai_text_stop_chat(mWritingSession);
        genai_text_destroy_session(&mWritingSession);
        chat_model_config_destroy(&mWritingConfig);
    }
}

MiniChatThread *MiniChatThread::getPtr()
{
    if (g_miniChatThread == nullptr) {
        g_miniChatThread = new MiniChatThread();
    }

    return g_miniChatThread;
}

void MiniChatThread::sendMessage(const QString message)
{
    QJsonObject data = QJsonDocument::fromJson(message.toUtf8()).object();

    if (!data.contains("msgType")) {
        KyInfo() << "Not carried msgType!";
        return;
    }

    if (!data["msgType"].isString()) {
        KyInfo() << "The type is not a string!";
        return;
    }

    QString msgType = data["msgType"].toString();
    if (msgType == "sendChatMsg") {
        sendChatMsg(data);
        return;
    }

    if (msgType == "sendStopMsg") {
        sendStopMsg(data);
        return;
    }

    if (msgType == "sendCopyText") {
        sendCopyText(data);
        return;
    }

    //TODO:需要基于readercontrol逻辑实现朗读功能，当前逻辑建议删除
//    if (msgType == "sendReadText") {
//        sendReadText(data);
//        return;
//    }

//    if (msgType == "sendToPauseReading") {
//        sendToPauseReading(data);
//        return;
//    }

    return;
}

void MiniChatThread::run()
{
    QEventLoop loop;

    initMiniChatThread();

    loop.exec();

    return;
}

void miniChatSessionCallback(ChatResult *result, void *userData) {
    KyInfo() << "writingSessionCallback";
    const char *message = chat_result_get_assistant_message(result);
    if (message == NULL) {
        KyInfo() << "Cannot get chat message!";
        return;
    }

    KyInfo() << "Chat message: " << QString::fromUtf8(message);

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

    QJsonObject msgBody;
    bool isEnd = chat_result_get_is_end(result);
    msgBody["isEnd"] = isEnd;
    msgBody["recvMsg"] = message;

    const char *reasonMessage = chat_result_get_reasoning_message(result);
    if ((reasonMessage != NULL) && (reasonMessage[0] != '\0')) {
        KyInfo() << "reasonMessage message: " << QString::fromUtf8(reasonMessage);
        msgBody["reasonMessage"] = reasonMessage;
    }

    msg["msgBody"] = msgBody;

    MiniChatThread *minichat = MiniChatThread::getPtr();
    if (minichat == NULL) {
        KyInfo() << "Writing thread not inited!";
        return;
    }

    Q_EMIT minichat->receiveMessage(QString::fromUtf8(QJsonDocument(msg).toJson()));

    return;
}

void MiniChatThread::initMiniChatThread()
{
    mWritingConfig = createWritingSessionConfig();
    if (mWritingConfig == NULL) {
        KyInfo() << "Failed to create writing session config!";
        return;
    }

    mWritingSession = genai_text_create_session();
    if (mWritingSession == NULL) {
        KyInfo() << "Failed to create writing session!";
        return;
    }

    genai_text_set_model_config(mWritingSession, NULL);

    genai_text_init_session(mWritingSession);

    genai_text_result_set_callback(mWritingSession, miniChatSessionCallback, NULL);

    return;
}

ChatModelConfig *MiniChatThread::createWritingSessionConfig()
{
    ChatModelConfig *config = chat_model_config_create();
    if (config == NULL) {
        KyInfo() << "Failed to create model config!";
        return NULL;
    }

    return config;
}

void MiniChatThread::sendChatMsg(const QJsonObject &data)
{
    if (!data.contains("msgBody")) {
        KyInfo() << "Not carried msgBody!";
        return;
    }

    if (!data["msgBody"].isObject()) {
        KyInfo() << "The type is not an object!";
        return;
    }

    QJsonObject msgBody = data["msgBody"].toObject();
    if(!msgBody.contains("inputMsg") || !msgBody["inputMsg"].isString()) {
        KyInfo() << "Not carried inputMsg!";
        return;
    }

    QString inputMsg = msgBody["inputMsg"].toString();
    if (mWritingSession == NULL) {
        KyInfo() << "Writing session  not initialized!";
        return;
    }

    KyInfo() << "Writing inputMsg : " << inputMsg;

    QString reference;
    if(!msgBody.contains("reference") || !msgBody["reference"].isString() || msgBody["reference"].toString().isEmpty()) {
        KyInfo() << "Not carried reference!";
        // 如果用户没有输入参考内容，则参考内容为空
        reference = "";
    } else {
        reference = QString("内容为: “%1”。").arg(msgBody["reference"].toString());
    }

    QString input = inputMsg + "。" + reference;

    KyInfo() << "input : " << input;

    genai_text_chat_async(mWritingSession, input.toUtf8().constData());

    return;
}

void MiniChatThread::sendStopMsg(const QJsonObject &data)
{
    KyInfo() << "sendStopMsg : ";

    if (mWritingSession == NULL) {
        KyInfo() << "Writing session not initialized!";
        return;
    }

    genai_text_stop_chat(mWritingSession);

    return;
}

void MiniChatThread::sendCopyText(const QJsonObject &data)
{
    KyInfo() << "sendCopyText : ";

    if (!data.contains("msgBody")) {
        KyInfo() << "Not carried msgBody!";
        return;
    }

    if (!data["msgBody"].isObject()) {
        KyInfo() << "The type is not an object!";
        return;
    }

    QJsonObject msgBody = data["msgBody"].toObject();
    if(!msgBody.contains("copyText") || !msgBody["copyText"].isString()) {
        KyInfo() << "Not carried copyText!";
        return;
    }

    QString copyText = msgBody["copyText"].toString();

    KyInfo() << "sendCopyText : " << copyText;

    if (mClipboard == nullptr) {
        KyInfo() << "Clipboard not initialized!";
        return;
    }

    mClipboard->setText(copyText);

    return;
}

