#include "WeChatSession.h"
#include "../ServiceManager.h"
#include <BoostLog.h>
#include <DateTime.h>

WeChatSession::WeChatSession(const std::string_view &username) : m_username(username) {
    m_lastAccessedTime = std::chrono::system_clock::now();
    initiate();
}

std::string WeChatSession::processInput(const std::string_view &text) {
    ProcessInputEvent e;
    e.text = text;
    process_event(e);
    m_lastAccessedTime = std::chrono::system_clock::now();

    std::string ret = std::move(m_reply);
    return ret;
}

void WeChatSession::printHelp() {
    std::ostringstream oss;
    oss << "1:设置闹钟" << std::endl;
    oss << "2:TTS" << std::endl;
    oss << "3:当前时间" << std::endl;
    oss << "4:随机播放音乐" << std::endl;
    oss << "5:停止播放音乐" << std::endl;
    oss << "<其它>:帮助" << std::endl;
    setReply(oss.str());
}

void WeChatSession::printCurrentDateTime() {
    auto manager = Amass::Singleton<ServiceManager>::instance();
    if (manager) manager->sendMessage<CurrentDatetimeService>(CurrentDatetime);
    setReply("艾玛收到！将为您播报当前时间");
}

void WeChatSession::playRandomMusic() {
    auto manager = Amass::Singleton<ServiceManager>::instance();
    if (manager) manager->sendMessage<PlayRandomMusicService>(PlayRandomMusic);
    setReply("艾玛收到！将为您随机播放音乐");
}

void WeChatSession::stopPlayMusic() {
    auto manager = Amass::Singleton<ServiceManager>::instance();
    if (manager) manager->sendMessage(StopPlayMusic);
    setReply("艾玛收到！正在为您停止播放音乐");
}

std::chrono::system_clock::time_point WeChatSession::lastAccessedTime() const {
    return m_lastAccessedTime;
}

void WeChatSession::setReply(std::string &&reply) {
    m_reply = std::move(reply);
}

boost::statechart::result IdleState::react(const ProcessInputEvent &e) {
    auto &text = e.text;
    if (text == "1") {
        outermost_context().setReply("请输入闹钟时间:");
        return transit<SetAlarmState>();
    } else if (text == "2") {
        outermost_context().setReply("请输入TTS文字:");
        return transit<SetTtsState>();
    } else if (text == "3") {
        outermost_context().printCurrentDateTime();
        return discard_event();
    } else if (text == "4") {
        outermost_context().playRandomMusic();
        return discard_event();
    } else if (text == "5") {
        outermost_context().stopPlayMusic();
        return discard_event();
    } else {
        outermost_context().stopPlayMusic();
        outermost_context().printHelp();
        return discard_event();
    }
}

boost::statechart::result SetAlarmState::react(const ProcessInputEvent &e) {
    auto &text = e.text;
    auto [hour, minute, second] = DateTime::parseTime(text);
    auto manager = Amass::Singleton<ServiceManager>::instance();
    if (manager) manager->sendMessage<SetAlarmClockService>(SetAlarmClock, hour, minute);
    std::ostringstream oss;
    oss << "set alarm clock at " << (int)hour << ":" << (int)minute;
    this->outermost_context().setReply(oss.str());
    return transit<IdleState>();
}

SetAlarmState::SetAlarmState() {
}

boost::statechart::result SetTtsState::react(const ProcessInputEvent &e) {
    auto manager = Amass::Singleton<ServiceManager>::instance();
    if (manager) manager->sendMessage(TextToSpeech, e.text);
    outermost_context().setReply(e.text.data());
    return transit<IdleState>();
}
