#include "r1_voice/conversation.hh"

#include <chrono>
#include <iostream>
#include <thread>

namespace r1_voice {

Conversation::Conversation(
    ConversationConfig config)
    : config_(std::move(config))
    , stt_(config_.stt)
    , llm_(config_.llm)
    , tts_(config_.tts)
{
}

bool Conversation::init(
    const std::string& network_interface)
{
    return tts_.init(
        network_interface
    );
}

void Conversation::run()
{
    std::cout
        << "\n"
        << "====================================\n"
        << " R1 Voice Assistant\n"
        << "====================================\n"
        << "Speak to R1.\n"
        << "Press Ctrl+C to exit.\n"
        << '\n';

    tts_.speak(
        "Ahoj. Jsem připraven."
    );

    // Give TTS time to finish before listening.
    std::this_thread::sleep_for(
        std::chrono::seconds(2)
    );

    while (true) {

        const std::string user =
            stt_.listen();

        if (user.empty())
            continue;

        try {

            const std::string response =
                llm_.chat(user);

            if (response.empty())
                continue;

            tts_.speak(response);

            /*
             * Avoid immediately hearing the robot's
             * own TTS output as the next user utterance.
             *
             * Later we can replace this with proper
             * audio echo suppression / playback state.
             */
            const int estimated_ms =
                1000 +
                static_cast<int>(
                    response.size() * 50
                );

            std::this_thread::sleep_for(
                std::chrono::milliseconds(
                    estimated_ms
                )
            );
        }
        catch (const std::exception& e) {

            std::cerr
                << "Conversation error: "
                << e.what()
                << '\n';

            tts_.speak(
                "Promiň, při zpracování odpovědi nastala chyba."
            );

            std::this_thread::sleep_for(
                std::chrono::seconds(2)
            );
        }
    }
}

} // namespace r1_voice
