#include "MCPServerTools.hpp"
#include "../../services/LLMService.hpp"
#include "../../services/StorageService.hpp"
#include "../../services/VoiceService.hpp"

#include <spdlog/spdlog.h>

namespace celuna::tools {

MCPServerTools::MCPServerTools(
    LLMService* llm,
    StorageService* storage,
    VoiceService* voice
) : m_llmService(llm),
    m_storageService(storage),
    m_voiceService(voice)
{
}

std::vector<ToolDefinition> MCPServerTools::getToolDefinitions() {
    std::vector<ToolDefinition> tools;

    // Tool 1: chat_with_celuna (PRIORITÉ)
    if (m_llmService) {
        tools.push_back({
            "chat_with_celuna",
            "Dialogue with Celuna AI assistant (Claude Sonnet 4). Send a message and get an intelligent response with access to Celuna's knowledge and capabilities.",
            {
                {"type", "object"},
                {"properties", {
                    {"message", {
                        {"type", "string"},
                        {"description", "Message to send to Celuna"}
                    }},
                    {"conversation_id", {
                        {"type", "string"},
                        {"description", "Conversation ID for continuity (optional)"}
                    }},
                    {"system_prompt", {
                        {"type", "string"},
                        {"description", "Custom system prompt (optional)"}
                    }}
                }},
                {"required", json::array({"message"})}
            },
            [this](const json& input) { return handleChatWithCeluna(input); }
        });
    }

    // Tool 2: transcribe_audio
    if (m_voiceService) {
        tools.push_back({
            "transcribe_audio",
            "Transcribe audio file to text using Speech-to-Text (Whisper.cpp, OpenAI Whisper API, or Google Speech). Supports WAV, MP3, and other common audio formats.",
            {
                {"type", "object"},
                {"properties", {
                    {"file_path", {
                        {"type", "string"},
                        {"description", "Path to audio file"}
                    }},
                    {"language", {
                        {"type", "string"},
                        {"description", "Language code (e.g., 'fr', 'en'). Default: 'fr'"}
                    }}
                }},
                {"required", json::array({"file_path"})}
            },
            [this](const json& input) { return handleTranscribeAudio(input); }
        });

        // Tool 3: text_to_speech
        tools.push_back({
            "text_to_speech",
            "Convert text to speech audio file using Text-to-Speech synthesis. Generates audio in WAV format.",
            {
                {"type", "object"},
                {"properties", {
                    {"text", {
                        {"type", "string"},
                        {"description", "Text to synthesize"}
                    }},
                    {"output_file", {
                        {"type", "string"},
                        {"description", "Output audio file path (WAV)"}
                    }},
                    {"voice", {
                        {"type", "string"},
                        {"description", "Voice identifier (e.g., 'fr-fr', 'en-us'). Default: 'fr-fr'"}
                    }}
                }},
                {"required", json::array({"text", "output_file"})}
            },
            [this](const json& input) { return handleTextToSpeech(input); }
        });
    }

    // Tool 4: save_memory
    if (m_storageService) {
        tools.push_back({
            "save_memory",
            "Save a note or memory to AISSIA's persistent storage. Memories can be tagged and searched later.",
            {
                {"type", "object"},
                {"properties", {
                    {"title", {
                        {"type", "string"},
                        {"description", "Memory title"}
                    }},
                    {"content", {
                        {"type", "string"},
                        {"description", "Memory content"}
                    }},
                    {"tags", {
                        {"type", "array"},
                        {"items", {{"type", "string"}}},
                        {"description", "Tags for categorization (optional)"}
                    }}
                }},
                {"required", json::array({"title", "content"})}
            },
            [this](const json& input) { return handleSaveMemory(input); }
        });

        // Tool 5: search_memories
        tools.push_back({
            "search_memories",
            "Search through saved memories and notes in AISSIA's storage. Returns matching memories with relevance scores.",
            {
                {"type", "object"},
                {"properties", {
                    {"query", {
                        {"type", "string"},
                        {"description", "Search query"}
                    }},
                    {"limit", {
                        {"type", "integer"},
                        {"description", "Maximum results to return. Default: 10"}
                    }}
                }},
                {"required", json::array({"query"})}
            },
            [this](const json& input) { return handleSearchMemories(input); }
        });
    }

    return tools;
}

json MCPServerTools::execute(const std::string& toolName, const json& input) {
    if (toolName == "chat_with_celuna") {
        return handleChatWithCeluna(input);
    } else if (toolName == "transcribe_audio") {
        return handleTranscribeAudio(input);
    } else if (toolName == "text_to_speech") {
        return handleTextToSpeech(input);
    } else if (toolName == "save_memory") {
        return handleSaveMemory(input);
    } else if (toolName == "search_memories") {
        return handleSearchMemories(input);
    }

    return {
        {"error", "Unknown tool: " + toolName}
    };
}

// ============================================================================
// Tool Handlers
// ============================================================================

json MCPServerTools::handleChatWithCeluna(const json& input) {
    if (!m_llmService) {
        return {{"error", "LLMService not available"}};
    }

    try {
        std::string message = input["message"];
        std::string conversationId = input.value("conversation_id", "");
        std::string systemPrompt = input.value("system_prompt", "");

        spdlog::info("[chat_with_celuna] Message: {}", message.substr(0, 100));

        // Call synchronous LLM method
        auto response = m_llmService->sendMessageSync(message, conversationId, systemPrompt);

        return {
            {"response", response.text},
            {"conversation_id", conversationId},
            {"tokens", response.tokens},
            {"iterations", response.iterations}
        };
    } catch (const std::exception& e) {
        spdlog::error("[chat_with_celuna] Error: {}", e.what());
        return {{"error", e.what()}};
    }
}

json MCPServerTools::handleTranscribeAudio(const json& input) {
    if (!m_voiceService) {
        return {{"error", "VoiceService not available"}};
    }

    try {
        std::string filePath = input["file_path"];
        std::string language = input.value("language", "fr");

        spdlog::info("[transcribe_audio] File: {}, Language: {}", filePath, language);

        // Call synchronous STT method
        std::string text = m_voiceService->transcribeFileSync(filePath, language);

        return {
            {"text", text},
            {"file", filePath},
            {"language", language}
        };
    } catch (const std::exception& e) {
        spdlog::error("[transcribe_audio] Error: {}", e.what());
        return {{"error", e.what()}};
    }
}

json MCPServerTools::handleTextToSpeech(const json& input) {
    if (!m_voiceService) {
        return {{"error", "VoiceService not available"}};
    }

    try {
        std::string text = input["text"];
        std::string outputFile = input["output_file"];
        std::string voice = input.value("voice", "fr-fr");

        spdlog::info("[text_to_speech] Text: {}, Output: {}", text.substr(0, 50), outputFile);

        // Call synchronous TTS method
        bool success = m_voiceService->textToSpeechSync(text, outputFile, voice);

        if (success) {
            return {
                {"success", true},
                {"file", outputFile},
                {"voice", voice}
            };
        } else {
            return {{"error", "TTS generation failed"}};
        }
    } catch (const std::exception& e) {
        spdlog::error("[text_to_speech] Error: {}", e.what());
        return {{"error", e.what()}};
    }
}

json MCPServerTools::handleSaveMemory(const json& input) {
    if (!m_storageService) {
        return {{"error", "StorageService not available"}};
    }

    try {
        std::string title = input["title"];
        std::string content = input["content"];
        std::vector<std::string> tags;

        if (input.contains("tags") && input["tags"].is_array()) {
            for (const auto& tag : input["tags"]) {
                tags.push_back(tag.get<std::string>());
            }
        }

        spdlog::info("[save_memory] Title: {}", title);

        // TODO: Implement saveMemorySync in StorageService
        // For now, return not implemented
        return json({
            {"error", "save_memory not yet implemented"},
            {"note", "StorageService sync methods need to be added"},
            {"title", title}
        });
    } catch (const std::exception& e) {
        spdlog::error("[save_memory] Error: {}", e.what());
        return {{"error", e.what()}};
    }
}

json MCPServerTools::handleSearchMemories(const json& input) {
    if (!m_storageService) {
        return {{"error", "StorageService not available"}};
    }

    try {
        std::string query = input["query"];
        int limit = input.value("limit", 10);

        spdlog::info("[search_memories] Query: {}, Limit: {}", query, limit);

        // TODO: Implement searchMemoriesSync in StorageService
        // For now, return not implemented
        return json({
            {"error", "search_memories not yet implemented"},
            {"note", "StorageService sync methods need to be added"},
            {"query", query},
            {"limit", limit}
        });
    } catch (const std::exception& e) {
        spdlog::error("[search_memories] Error: {}", e.what());
        return {{"error", e.what()}};
    }
}

} // namespace celuna::tools
