// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "audioaiassistant_p.h"
#include "utils/util.h"
#include "utils/compliance/atspidesktop.h"
#include "utils/compliance/qselectionmonitor.h"
#include "private/eaiexecutor.h"
#include "gui/iatwidget.h"
#include "wordwizard/wordwizard.h"
#include "private/baseclipboard.h"

#include "compliance/audioaiassistantmainwindowproxy.h"
#include "compliance/audioaiassistantiatproxy.h"
#include "compliance/audioaiassistantttsproxy.h"

#include <QDBusConnection>
#include <QDebug>
#include <QClipboard>
#include <QApplication>
#include <QDateTime>


#define  EVENT_TIME_INTERVAL 10

UOSAI_USE_NAMESPACE

AudioAiassistantPrivate::AudioAiassistantPrivate(AudioAiassistant *parent) : q(parent)
{

}

AudioAiassistantPrivate::~AudioAiassistantPrivate()
{
    if (m_tts) {
        delete m_tts;
        m_tts = nullptr;
    }
    if (m_asr) {
        delete m_asr;
        m_asr = nullptr;
    }
}

AudioAiassistant::AudioAiassistant(QObject *parent)
    : QObject(parent)
    , d(new AudioAiassistantPrivate(this))
{
    m_selectclip = BaseClipboard::ttsInstance();
}

AudioAiassistant::~AudioAiassistant()
{
    delete d;
    d = nullptr;
}

bool AudioAiassistant::registerInterface()
{
    QDBusConnection connection = QDBusConnection::sessionBus();

    if (!connection.registerService("com.iflytek.aiassistant")){
        qWarning() << "service 'com.iflytek.aiassistant' is already registered by another application";
        return false;
    }

    // init AtspiDesktop
    AudioAiassistantSetting::instance();
    AtspiDesktop::getInstance()->start();
    QSelectionMonitor::getInstance();

    AudioAiassistantMainWindowProxy *mainWin = new AudioAiassistantMainWindowProxy(this);
    connection.registerObject(mainWin->proxyPath(), mainWin, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals);

    AudioAiassistantIatProxy* iatdbusServiceProxy = new AudioAiassistantIatProxy(this);
    connection.registerObject(iatdbusServiceProxy->proxyPath(), iatdbusServiceProxy, QDBusConnection::ExportAllSlots);

    AudioAiassistantTtsProxy* ttsdbusServiceProxy = new AudioAiassistantTtsProxy(this);
    connection.registerObject(ttsdbusServiceProxy->proxyPath(), ttsdbusServiceProxy, QDBusConnection::ExportAllSlots);

    return true;
}

bool AudioAiassistant::isTTSInWorking()
{
    bool ret = false;
    if (d->m_tts)
        ret = d->m_tts->isWorking();
    return ret;
}

void AudioAiassistant::stopTTSDirectly()
{
    if (d->m_tts)
        d->m_tts->stopTTS();
}

// 朗读
void AudioAiassistant::textToSpeech()
{
    if (!AudioAiassistantSetting::instance()->getTTSEnable()) {
        qWarning() << "Tts switch is off";
        return;
    }

    QString text = m_selectclip->getClipText().trimmed();
    if (text.isEmpty()) {
        qInfo() << "no selected text to speech";
        Util::playSystemSound_SSE_Error();
        return;
    }

    if (d->m_tts && d->m_tts->isWorking()) {
        d->m_tts->stopTTS();
        qInfo() << "tts is in working ,so stop tts!";
        return;
    }

    if (!d->m_tts) {
        d->m_tts = new TtsWidget();
    }

    d->m_tts->stopTTS();
    bool windowVisible = AudioAiassistantSetting::instance()->getEnableWindow();
    d->m_tts->startTTS(text, windowVisible);
}

// 听写
void AudioAiassistant::speechToText()
{
    emit this->sigIatTriggered();

    // 检查目前是否可写
    if (!WordWizard::fcitxWritable()) {
        qWarning() << "not writable";
        // 某些情况下，右键菜单将焦点还回编辑框较慢，所以重试一次
        QTimer::singleShot(500, [&] {
            if (!WordWizard::fcitxWritable()) {
                qWarning() << "not writable again";
                return;
            }

            d->m_iat = new IatWidget(this);
            d->m_iat->startIat();
        });
        return;
    }

    // 几乎任何一个键盘事件或鼠标事件，实例都会自动退出（此实例将自动释放）
    d->m_iat = new IatWidget(this);
    d->m_iat->startIat();
}

//转写
QString AudioAiassistant::startAsr(const QVariantMap &param)
{
    if (!d->m_asr) {
        d->m_asr = new AsrWrapper();
        connect(d->m_asr,&AsrWrapper::onNotify,this,&AudioAiassistant::onNotify,Qt::DirectConnection);
    }
    return d->m_asr->startAsr(param);
}

void AudioAiassistant::stopAsr()
{
    if (d->m_asr) {
        d->m_asr->stopAsr();
    }
}

