#pragma once

#include <grove/IModule.h>
#include <grove/JsonDataNode.h>

#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <memory>
#include <string>
#include <queue>

namespace celuna {

/**
 * @brief Voice Module - Voice interaction logic only
 *
 * Handles voice interaction logic without platform-specific TTS/STT.
 * Communicates with VoiceService via IIO pub/sub.
 *
 * Publie sur:
 * - "voice:speak"        : Request TTS
 * - "voice:listen"       : Request STT
 *
 * Souscrit a:
 * - "ai:response"            : AI response to speak
 * - "ai:suggestion"          : AI suggestion to speak (priority)
 * - "notification:speak"     : Notification to speak
 * - "voice:speaking_started" : TTS started
 * - "voice:speaking_ended"   : TTS ended
 * - "voice:transcription"    : STT result
 */
class VoiceModule : public grove::IModule {
public:
    VoiceModule();
    ~VoiceModule() override = default;

    // IModule interface
    void process(const grove::IDataNode& input) override;
    void setConfiguration(const grove::IDataNode& configNode, grove::IIO* io,
                         grove::ITaskScheduler* scheduler) override;
    const grove::IDataNode& getConfiguration() override;
    std::unique_ptr<grove::IDataNode> getHealthStatus() override;
    void shutdown() override;
    std::unique_ptr<grove::IDataNode> getState() override;
    void setState(const grove::IDataNode& state) override;
    std::string getType() const override { return "VoiceModule"; }
    bool isIdle() const override { return !m_isSpeaking; }
    int getVersion() const override { return 2; }

private:
    // Configuration
    bool m_ttsEnabled = true;
    bool m_sttEnabled = true;
    std::string m_language = "fr";

    // State
    bool m_isSpeaking = false;
    int m_totalSpoken = 0;
    int m_totalTranscribed = 0;

    // Services
    grove::IIO* m_io = nullptr;
    std::unique_ptr<grove::JsonDataNode> m_config;
    std::shared_ptr<spdlog::logger> m_logger;

    // Helpers
    void processMessages();
    void requestSpeak(const std::string& text, bool priority = false);
    void handleAIResponse(const grove::IDataNode& data);
    void handleSuggestion(const grove::IDataNode& data);
    void handleNotificationSpeak(const grove::IDataNode& data);
    void handleSpeakingStarted(const grove::IDataNode& data);
    void handleSpeakingEnded(const grove::IDataNode& data);
    void handleTranscription(const grove::IDataNode& data);

    // Tool handlers
    void handleToolCommand(const grove::IDataNode& request);
};

} // namespace celuna

extern "C" {
    grove::IModule* createModule();
    void destroyModule(grove::IModule* module);
}
