#pragma once

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

#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <nlohmann/json.hpp>
#include <memory>
#include <string>

namespace celuna {

/**
 * @brief AI Assistant Module - Pure business logic
 *
 * Handles AI-related logic without any infrastructure code.
 * Communicates with LLMService via IIO pub/sub.
 *
 * Publie sur:
 * - "llm:request"    : Request LLM response
 * - "ai:suggestion"  : Suggestion proactive
 *
 * Souscrit a:
 * - "llm:response"               : Response from LLM
 * - "llm:error"                  : Error from LLM
 * - "ai:query"                   : User query
 * - "voice:transcription"        : STT result
 * - "scheduler:hyperfocus_alert" : Generate intervention
 * - "scheduler:break_reminder"   : Generate break suggestion
 */
class AIModule : public grove::IModule {
public:
    AIModule();
    ~AIModule() 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 "AIModule"; }
    bool isIdle() const override { return !m_awaitingResponse; }
    int getVersion() const override { return 2; }

private:
    // Configuration
    std::string m_systemPrompt;
    int m_maxIterations = 10;

    // State
    int m_totalQueries = 0;
    int m_totalTokens = 0;
    bool m_awaitingResponse = false;
    std::string m_currentConversationId = "default";

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

    // Helpers
    void processMessages();
    void sendQuery(const std::string& query);
    void handleLLMResponse(const grove::IDataNode& data);
    void handleLLMError(const grove::IDataNode& data);
    void handleHyperfocusAlert(const grove::IDataNode& data);
    void handleBreakReminder(const grove::IDataNode& data);
    void publishSuggestion(const std::string& message, int duration);
};

} // namespace celuna

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