package mcp

import (
	"context"
	"encoding/json"
	"fmt"
	"log/slog"
	"strings"
	"sync"
	"time"

	"github.com/mark3labs/mcp-go/client"
	"github.com/mark3labs/mcp-go/client/transport"
	"github.com/mark3labs/mcp-go/mcp"
	"sketch.dev/llm"
)

// ServerConfig represents the configuration for an MCP server
type ServerConfig struct {
	Name    string            `json:"name,omitempty"`
	Type    string            `json:"type,omitempty"`    // "stdio", "http", "sse"
	URL     string            `json:"url,omitempty"`     // for http/sse
	Command string            `json:"command,omitempty"` // for stdio
	Args    []string          `json:"args,omitempty"`    // for stdio
	Env     map[string]string `json:"env,omitempty"`     // for stdio
	Headers map[string]string `json:"headers,omitempty"` // for http/sse
}

// MCPManager manages multiple MCP server connections
type MCPManager struct {
	mu      sync.RWMutex
	clients map[string]*MCPClientWrapper
}

// MCPClientWrapper wraps an MCP client connection
type MCPClientWrapper struct {
	name   string
	config ServerConfig
	client *client.Client
	tools  []*llm.Tool
}

// MCPServerConnection represents a successful MCP server connection with its tools
type MCPServerConnection struct {
	ServerName string
	Tools      []*llm.Tool
	ToolNames  []string // Original tool names without server prefix
}

// NewMCPManager creates a new MCP manager
func NewMCPManager() *MCPManager {
	return &MCPManager{
		clients: make(map[string]*MCPClientWrapper),
	}
}

// ParseServerConfigs parses JSON configuration strings into ServerConfig structs
func ParseServerConfigs(ctx context.Context, configs []string) ([]ServerConfig, []error) {
	if len(configs) == 0 {
		return nil, nil
	}

	var serverConfigs []ServerConfig
	var errors []error

	for i, configStr := range configs {
		var config ServerConfig
		if err := json.Unmarshal([]byte(configStr), &config); err != nil {
			slog.ErrorContext(ctx, "Failed to parse MCP server config", "config", configStr, "error", err)
			errors = append(errors, fmt.Errorf("config %d: %w", i, err))
			continue
		}
		// Require a name
		if config.Name == "" {
			errors = append(errors, fmt.Errorf("config %d: name is required", i))
			continue
		}
		serverConfigs = append(serverConfigs, config)
	}

	return serverConfigs, errors
}

// ConnectToServers connects to multiple MCP servers in parallel
func (m *MCPManager) ConnectToServers(ctx context.Context, configs []string, timeout time.Duration) ([]MCPServerConnection, []error) {
	serverConfigs, parseErrors := ParseServerConfigs(ctx, configs)
	if len(serverConfigs) == 0 {
		if len(parseErrors) > 0 {
			return nil, parseErrors
		}
		return nil, nil
	}
	return m.ConnectToServerConfigs(ctx, serverConfigs, timeout, parseErrors)
} // ConnectToServerConfigs connects to multiple parsed MCP server configs in parallel
func (m *MCPManager) ConnectToServerConfigs(ctx context.Context, serverConfigs []ServerConfig, timeout time.Duration, existingErrors []error) ([]MCPServerConnection, []error) {
	if len(serverConfigs) == 0 {
		return nil, existingErrors
	}

	slog.InfoContext(ctx, "Connecting to MCP servers", "count", len(serverConfigs), "timeout", timeout)

	// Connect to servers in parallel using sync.WaitGroup
	type result struct {
		tools         []*llm.Tool
		err           error
		serverName    string
		originalTools []string // Original tool names without server prefix
	}

	results := make(chan result, len(serverConfigs))
	ctxWithTimeout, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()

	for _, config := range serverConfigs {
		go func(cfg ServerConfig) {
			slog.InfoContext(ctx, "Connecting to MCP server", "server", cfg.Name, "type", cfg.Type, "url", cfg.URL, "command", cfg.Command)
			tools, originalToolNames, err := m.connectToServerWithNames(ctxWithTimeout, cfg)
			results <- result{
				tools:         tools,
				err:           err,
				serverName:    cfg.Name,
				originalTools: originalToolNames,
			}
		}(config)
	}

	// Collect results
	var connections []MCPServerConnection
	errors := make([]error, 0, len(existingErrors))
	errors = append(errors, existingErrors...)

	for range len(serverConfigs) {
		select {
		case res := <-results:
			if res.err != nil {
				slog.ErrorContext(ctx, "Failed to connect to MCP server", "server", res.serverName, "error", res.err)
				errors = append(errors, fmt.Errorf("MCP server %q: %w", res.serverName, res.err))
			} else {
				connection := MCPServerConnection{
					ServerName: res.serverName,
					Tools:      res.tools,
					ToolNames:  res.originalTools,
				}
				connections = append(connections, connection)
				slog.InfoContext(ctx, "Successfully connected to MCP server", "server", res.serverName, "tools", len(res.tools), "tool_names", res.originalTools)
			}
		case <-ctxWithTimeout.Done():
			errors = append(errors, fmt.Errorf("timeout connecting to MCP servers"))
			break
		}
	}

	return connections, errors
}

// connectToServerWithNames connects to a single MCP server and returns tools with original names
func (m *MCPManager) connectToServerWithNames(ctx context.Context, config ServerConfig) ([]*llm.Tool, []string, error) {
	tools, err := m.connectToServer(ctx, config)
	if err != nil {
		return nil, nil, err
	}

	// Extract original tool names (remove server prefix)
	originalNames := make([]string, len(tools))
	for i, tool := range tools {
		// Tool names are in format "servername_toolname"
		parts := strings.SplitN(tool.Name, "_", 2)
		if len(parts) == 2 {
			originalNames[i] = parts[1]
		} else {
			originalNames[i] = tool.Name // fallback if no prefix
		}
	}

	return tools, originalNames, nil
}

// connectToServer connects to a single MCP server
func (m *MCPManager) connectToServer(ctx context.Context, config ServerConfig) ([]*llm.Tool, error) {
	var mcpClient *client.Client
	var err error

	// Convert environment variables to []string format
	var envVars []string
	for k, v := range config.Env {
		envVars = append(envVars, k+"="+v)
	}

	switch config.Type {
	case "stdio", "":
		if config.Command == "" {
			return nil, fmt.Errorf("command is required for stdio transport")
		}
		mcpClient, err = client.NewStdioMCPClient(config.Command, envVars, config.Args...)
	case "http":
		if config.URL == "" {
			return nil, fmt.Errorf("URL is required for HTTP transport")
		}
		// Use streamable HTTP client for HTTP transport
		var httpOptions []transport.StreamableHTTPCOption
		if len(config.Headers) > 0 {
			httpOptions = append(httpOptions, transport.WithHTTPHeaders(config.Headers))
		}
		mcpClient, err = client.NewStreamableHttpClient(config.URL, httpOptions...)
	case "sse":
		if config.URL == "" {
			return nil, fmt.Errorf("URL is required for SSE transport")
		}
		var sseOptions []transport.ClientOption
		if len(config.Headers) > 0 {
			sseOptions = append(sseOptions, transport.WithHeaders(config.Headers))
		}
		mcpClient, err = client.NewSSEMCPClient(config.URL, sseOptions...)
	default:
		return nil, fmt.Errorf("unsupported MCP transport type: %s", config.Type)
	}

	if err != nil {
		return nil, fmt.Errorf("failed to create MCP client: %w", err)
	}

	// Start the client first
	if err := mcpClient.Start(ctx); err != nil {
		return nil, fmt.Errorf("failed to start MCP client: %w", err)
	}

	// Initialize the client
	initReq := mcp.InitializeRequest{
		Params: mcp.InitializeParams{
			ProtocolVersion: mcp.LATEST_PROTOCOL_VERSION,
			Capabilities:    mcp.ClientCapabilities{},
			ClientInfo: mcp.Implementation{
				Name:    "sketch",
				Version: "1.0.0",
			},
		},
	}
	if _, err := mcpClient.Initialize(ctx, initReq); err != nil {
		return nil, fmt.Errorf("failed to initialize MCP client: %w", err)
	}

	// Get available tools
	toolsReq := mcp.ListToolsRequest{}
	toolsResp, err := mcpClient.ListTools(ctx, toolsReq)
	if err != nil {
		return nil, fmt.Errorf("failed to list tools: %w", err)
	}

	// Convert MCP tools to llm.Tool
	llmTools, err := m.convertMCPTools(config.Name, mcpClient, toolsResp.Tools)
	if err != nil {
		return nil, fmt.Errorf("failed to convert tools: %w", err)
	}

	// Store the client
	clientWrapper := &MCPClientWrapper{
		name:   config.Name,
		config: config,
		client: mcpClient,
		tools:  llmTools,
	}

	m.mu.Lock()
	m.clients[config.Name] = clientWrapper
	m.mu.Unlock()

	return llmTools, nil
}

// convertMCPTools converts MCP tools to llm.Tool format
func (m *MCPManager) convertMCPTools(serverName string, mcpClient *client.Client, mcpTools []mcp.Tool) ([]*llm.Tool, error) {
	var llmTools []*llm.Tool

	for _, mcpTool := range mcpTools {
		// Convert the input schema
		schemaBytes, err := json.Marshal(mcpTool.InputSchema)
		if err != nil {
			return nil, fmt.Errorf("failed to marshal input schema for tool %s: %w", mcpTool.Name, err)
		}

		llmTool := &llm.Tool{
			Name:        fmt.Sprintf("%s_%s", serverName, mcpTool.Name),
			Description: mcpTool.Description,
			InputSchema: json.RawMessage(schemaBytes),
			Run: func(toolName string, client *client.Client) func(ctx context.Context, input json.RawMessage) ([]llm.Content, error) {
				return func(ctx context.Context, input json.RawMessage) ([]llm.Content, error) {
					result, err := m.executeMCPTool(ctx, client, toolName, input)
					if err != nil {
						return nil, err
					}
					// Convert result to llm.Content
					return []llm.Content{llm.StringContent(fmt.Sprintf("%v", result))}, nil
				}
			}(mcpTool.Name, mcpClient),
		}

		llmTools = append(llmTools, llmTool)
	}

	return llmTools, nil
}

// executeMCPTool executes an MCP tool call
func (m *MCPManager) executeMCPTool(ctx context.Context, mcpClient *client.Client, toolName string, input json.RawMessage) (any, error) {
	// Add timeout for tool execution
	ctxWithTimeout, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	// Parse input arguments
	var args map[string]any
	if len(input) > 0 {
		if err := json.Unmarshal(input, &args); err != nil {
			return nil, fmt.Errorf("failed to parse tool arguments: %w", err)
		}
	}

	// Call the MCP tool
	req := mcp.CallToolRequest{
		Params: mcp.CallToolParams{
			Name:      toolName,
			Arguments: args,
		},
	}
	resp, err := mcpClient.CallTool(ctxWithTimeout, req)
	if err != nil {
		return nil, fmt.Errorf("MCP tool call failed: %w", err)
	}

	// Return the content from the response
	return resp.Content, nil
}

// Close closes all MCP client connections
func (m *MCPManager) Close() {
	m.mu.Lock()
	defer m.mu.Unlock()

	for _, clientWrapper := range m.clients {
		if clientWrapper.client != nil {
			clientWrapper.client.Close()
		}
	}
	m.clients = make(map[string]*MCPClientWrapper)
}
