package com.emonster.taroaichat.service.llm.openrouter.tools;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Manages all available AI tools and provides methods to retrieve them
 * for API calls and execution.
 */
@Service
public class AIToolManager {

    private static final Logger LOG = LoggerFactory.getLogger(AIToolManager.class);

    private final Map<String, AITool> tools = new HashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();

    public AIToolManager(List<AITool> availableTools) {
        // Register all available tools
        for (AITool tool : availableTools) {
            register(tool);
        }
        LOG.info("Registered {} AI tools", tools.size());
    }

    /**
     * Register a tool to make it available for AI function calling.
     */
    public void register(AITool tool) {
        tools.put(tool.getName(), tool);
        LOG.debug("Registered AI tool: {}", tool.getName());
    }

    /**
     * Get a tool by name.
     */
    public Optional<AITool> getTool(String name) {
        return Optional.ofNullable(tools.get(name));
    }

    /**
     * Get all registered tools in OpenAI API format.
     */
    public List<Map<String, Object>> getToolsForApiCall() {
        List<Map<String, Object>> toolsList = new ArrayList<>();
        for (AITool tool : tools.values()) {
            toolsList.add(tool.toApiFormat());
        }
        return toolsList;
    }

    /**
     * Execute a tool by name with the given parameters.
     */
    public AITool.ToolResult executeTool(String toolName, Map<String, Object> parameters) {
        Optional<AITool> tool = getTool(toolName);

        if (tool.isEmpty()) {
            LOG.warn("Tool not found: {}", toolName);
            return AITool.ToolResult.failure("Tool not found: " + toolName);
        }

        try {
            LOG.info("Executing tool: {} with parameters: {}", toolName, parameters);
            return tool.get().execute(parameters);
        } catch (Exception e) {
            LOG.error("Error executing tool: " + toolName, e);
            return AITool.ToolResult.failure("Error executing tool: " + e.getMessage());
        }
    }

    /**
     * Check if any tools are registered.
     */
    public boolean hasTools() {
        return !tools.isEmpty();
    }

    /**
     * Get the count of registered tools.
     */
    public int getToolCount() {
        return tools.size();
    }
}
