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
}

// 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...)
		// TODO: Get the transport, cast it to *transport.Stdio, and start a goroutine to pipe stderr from the subprocess
		// to our subprocess, but with each line prefixed with the server name.
	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
	// TODO: Expose the timeout as a tool call argument.
	ctxWithTimeout, cancel := context.WithTimeout(ctx, 120*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)
}
