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

import com.google.genai.types.FunctionDeclaration;
import com.google.genai.types.Tool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

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

/**
 * Manages Gemini-native AI tools and provides methods to retrieve them
 * for Gemini API calls and execution.
 */
@Service
public class GeminiToolManager {
    
    private static final Logger LOG = LoggerFactory.getLogger(GeminiToolManager.class);
    
    private final Map<String, GeminiAITool> tools = new HashMap<>();
    
    public GeminiToolManager(List<GeminiAITool> availableTools) {
        // Register all available Gemini tools
        for (GeminiAITool tool : availableTools) {
            register(tool);
        }
        LOG.info("Registered {} Gemini AI tools", tools.size());
    }
    
    /**
     * Register a Gemini tool to make it available for AI function calling.
     */
    public void register(GeminiAITool tool) {
        tools.put(tool.getName(), tool);
        LOG.debug("Registered Gemini AI tool: {}", tool.getName());
    }
    
    /**
     * Get a tool by name.
     */
    public Optional<GeminiAITool> getTool(String name) {
        return Optional.ofNullable(tools.get(name));
    }
    
    /**
     * Get all registered tools as Gemini Tool objects (wrapping FunctionDeclarations).
     */
    public List<Tool> getToolsForGeminiApi() {
        return tools.values().stream()
            .map(GeminiAITool::toFunctionDeclaration)
            .map(functionDeclaration -> Tool.builder()
                .functionDeclarations(List.of(functionDeclaration))
                .build())
            .toList();
    }
    
    /**
     * Execute a tool by name with the given parameters.
     */
    public GeminiAITool.GeminiToolResult executeTool(String toolName, Map<String, Object> parameters) {
        Optional<GeminiAITool> tool = getTool(toolName);
        
        if (tool.isEmpty()) {
            LOG.warn("Gemini tool not found: {}", toolName);
            return GeminiAITool.GeminiToolResult.failure("Tool not found: " + toolName);
        }
        
        try {
            LOG.info("Executing Gemini tool: {} with parameters: {}", toolName, parameters);
            return tool.get().execute(parameters);
        } catch (Exception e) {
            LOG.error("Error executing Gemini tool: " + toolName, e);
            return GeminiAITool.GeminiToolResult.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();
    }
    
    /**
     * Get all tool names.
     */
    public List<String> getToolNames() {
        return tools.keySet().stream().toList();
    }
}