#include <QThread>
#include <QJsonDocument>
#include <QJsonObject>

#include <ukui-log4qt.h>

#include "meetingrecorder.h"
#include <kylin-ai/ai-base/speech.h>


struct SpeechItme
{
    QString name;
    QString start, end;
    QString content;
};
static QJsonObject jsonObject;

/**
 * @brief runtimeSpeechCallback
 *          聊天结果返回回调函数，数据流式返回
 * @param result
 * @param usr_data
 */
static void finishedCallback(void *usr_data)
{
    if (usr_data == nullptr) {
        qDebug() << "Invalid callback user data pointer.";
    }

    qDebug() << "zzzzzzzzzzzzzzzzz finish speech !!!!!!!!1";
}

/**
 * @brief runtimeSpeechCallback
 *          聊天结果返回回调函数，数据流式返回
 * @param result
 * @param usr_data
 */
static void MeetingCallback(RecognitionResult result, void *usr_data)
{
    if (usr_data == nullptr) {
        qDebug() << "Invalid callback user data pointer.";
    }
    MeetingRecorder *meetingRecorder = (MeetingRecorder*)usr_data;
    qDebug() << "zzzzzzz" << result.text_data;
    qDebug() << "zzzzzzz" << result.text_data_length;
    qDebug() << "zzzzzzz" << result.error_code;

//    QJsonObject jsonObject2;
//    jsonObject2["name"] = "Mr.wang";
//    jsonObject2["start"] = "00:00";
//    jsonObject2["end"] = "00:30";
//    jsonObject2["content"] = result.text_data;

//    QJsonDocument jsonDoc(jsonObject2);
//    QString jsonString = jsonDoc.toJson(QJsonDocument::Indented);
    emit meetingRecorder->sigShowSpeech(result.text_data);


}

MeetingRecorder::MeetingRecorder(QObject *parent) : QObject(parent)
{
    //设置录音格式
    m_audioFormat.setByteOrder(QAudioFormat::LittleEndian);
    m_audioFormat.setChannelCount(1);
    m_audioFormat.setCodec("audio/pcm");
    m_audioFormat.setSampleRate(16000);
    m_audioFormat.setSampleSize(16);
    m_audioFormat.setSampleType(QAudioFormat::SignedInt);

    // 判断设备，查看是否存在
    QAudioDeviceInfo devInfo = QAudioDeviceInfo::defaultInputDevice();
    if (devInfo.isNull()) {
        qWarning() << "No recording device was found!";
    }
    // 不支持格式，使用最接近格式
    if (!devInfo.isFormatSupported(m_audioFormat)) {  // 当前使用设备是否支持
        qWarning() << "Automatic conversion is made to the nearest format!";
        m_audioFormat = devInfo.nearestFormat(m_audioFormat);  // 转换为最接近格式
    }

    m_audioInput = new QAudioInput(devInfo, m_audioFormat, this);
//    connect(m_audioInput, &QAudioInput::stateChanged, this, &MeetingRecorder::handleStateChanged);

    m_audioInput->setNotifyInterval(10 * 1000);
    initSession();
    jsonObject["format"] = "pcm";
    jsonObject["rate"] = 16000;
    jsonObject["channel"] = 1;
}

MeetingRecorder::~MeetingRecorder()
{
    if (m_audioInput != nullptr) {
        m_audioInput->stop();
        delete m_audioInput;
    }
}

void MeetingRecorder::startMeetingRecord()
{
    qDebug() << "startRecord  meeting";

    m_audioRecInfo.open(QIODevice::ReadWrite | QIODevice::Truncate);
    m_audioInput->start(&m_audioRecInfo);
    const char *params = QJsonDocument(jsonObject).toJson(QJsonDocument::Indented);
    speech_start_continuous_recognition(this->session, params);
}

void MeetingRecorder::pauseMeetingRecord()
{
}

void MeetingRecorder::stopMeetingRecord()
{
    m_audioInput->stop();
    m_audioRecInfo.close();
    speech_stop_continuous_recognition(this->session);

}

void MeetingRecorder::initSession()
{
    //    QThread::create([this]{
            void *session = nullptr;
            SpeechResult ret = speech_create_session(&session);
            if (ret != SPEECH_SUCCESS || session == nullptr){
                KyInfo() << "meeting create session error:" << ret;
                return;
            }
            ret = speech_init_session(session);
            if (ret != SPEECH_SUCCESS){
                KyInfo() << "meeting init session error :" << ret;
                return;
            }
    //    })->start();

        this->session = session;
        //设置语音识别文字回调
        speech_set_recognizing_callback(this->session, MeetingCallback, this);
        //翻译一段语音识别，触发回调函数
        speech_set_recognized_callback(this->session, finishedCallback, this);
        m_audioRecInfo.setAudioSession(session);
        return;
}

void MeetingRecorder::closeSession()
{
    if(this->session != nullptr)
        speech_destory_session(this->session);
}
