package tools

import (
	"context"
	"fmt"
	"sync"

	"github.com/mark3labs/mcp-go/mcp"
	"github.com/rs/zerolog/log"
)

// Tool represents an MCP tool that can be registered and executed
type Tool interface {
	// Name returns the unique name of the tool
	Name() string

	// Description returns a human-readable description of the tool
	Description() string

	// InputSchema returns the JSON schema for the tool's input parameters
	InputSchema() map[string]any

	// Execute runs the tool with the given arguments and returns the result
	Execute(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error)
}

// Registry manages the collection of available MCP tools
type Registry struct {
	mu    sync.RWMutex
	tools map[string]Tool
}

// NewRegistry creates a new tools registry
func NewRegistry() *Registry {
	return &Registry{
		tools: make(map[string]Tool),
	}
}

// Register adds a tool to the registry
func (r *Registry) Register(tool Tool) error {
	if tool == nil {
		return fmt.Errorf("cannot register nil tool")
	}

	name := tool.Name()
	if name == "" {
		return fmt.Errorf("tool name cannot be empty")
	}

	r.mu.Lock()
	defer r.mu.Unlock()

	if _, exists := r.tools[name]; exists {
		return fmt.Errorf("tool with name %q already registered", name)
	}

	r.tools[name] = tool
	log.Debug().Str("tool", name).Msg("Tool registered successfully")

	return nil
}

// Unregister removes a tool from the registry
func (r *Registry) Unregister(name string) error {
	r.mu.Lock()
	defer r.mu.Unlock()

	if _, exists := r.tools[name]; !exists {
		return fmt.Errorf("tool with name %q not found", name)
	}

	delete(r.tools, name)
	log.Debug().Str("tool", name).Msg("Tool unregistered successfully")

	return nil
}

// Get retrieves a tool by name
func (r *Registry) Get(name string) (Tool, bool) {
	r.mu.RLock()
	defer r.mu.RUnlock()

	tool, exists := r.tools[name]
	return tool, exists
}

// List returns all registered tools as MCP tool definitions
func (r *Registry) List() []mcp.Tool {
	r.mu.RLock()
	defer r.mu.RUnlock()

	mcpTools := make([]mcp.Tool, 0, len(r.tools))

	for _, tool := range r.tools {
		mcpTool := mcp.NewTool(tool.Name(), mcp.WithDescription(tool.Description()))
		mcpTools = append(mcpTools, mcpTool)
	}

	return mcpTools
}

// Names returns a slice of all registered tool names
func (r *Registry) Names() []string {
	r.mu.RLock()
	defer r.mu.RUnlock()

	names := make([]string, 0, len(r.tools))
	for name := range r.tools {
		names = append(names, name)
	}

	return names
}

// Count returns the number of registered tools
func (r *Registry) Count() int {
	r.mu.RLock()
	defer r.mu.RUnlock()

	return len(r.tools)
}

// Execute runs a tool with the given arguments
func (r *Registry) Execute(ctx context.Context, name string, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
	tool, exists := r.Get(name)
	if !exists {
		return nil, fmt.Errorf("tool %q not found", name)
	}

	log.Debug().
		Str("tool", name).
		Interface("request", request).
		Msg("Executing tool")

	result, err := tool.Execute(ctx, request)
	if err != nil {
		log.Error().
			Err(err).
			Str("tool", name).
			Msg("Tool execution failed")
		return nil, fmt.Errorf("tool %q execution failed: %w", name, err)
	}

	log.Debug().
		Str("tool", name).
		Msg("Tool execution completed successfully")

	return result, nil
}

// Clear removes all tools from the registry
func (r *Registry) Clear() {
	r.mu.Lock()
	defer r.mu.Unlock()

	count := len(r.tools)
	r.tools = make(map[string]Tool)

	log.Debug().Int("count", count).Msg("Registry cleared")
}
