package tools

import (
	"context"
	"fmt"

	"github.com/ClareAI/astra-insight-mcp/internal/gateway"
	"github.com/ClareAI/astra-insight-mcp/internal/mcp"
)

func registerListConversations(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "list_conversations",
		Description: "List real user conversations for the agent. Returns conversation metadata including lead level, timestamps, and type. Use this to browse recent conversations and pick ones to inspect in detail.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"agent_id":   {Type: "string", Description: "Agent ID (platform agent ID)"},
				"contact_id": {Type: "string", Description: "Filter by contact ID"},
				"channel":    {Type: "string", Description: "Filter by channel"},
				"status":     {Type: "string", Description: "Filter by status"},
				"start_time": {Type: "string", Description: "Start time filter (YYYY-MM-DD HH:MM:SS.sss)"},
				"end_time":   {Type: "string", Description: "End time filter (YYYY-MM-DD HH:MM:SS.sss)"},
				"page":       {Type: "integer", Description: "Page number for pagination"},
				"limit":      {Type: "integer", Description: "Max results per page"},
			},
			Required: []string{"agent_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		agentID, _ := args["agent_id"].(string)
		if apiKey == "" || agentID == "" {
			return nil, fmt.Errorf("api_key and agent_id are required")
		}

		opts := gateway.ConversationListOpts{AgentID: agentID}
		if v, ok := args["contact_id"].(string); ok {
			opts.ContactID = v
		}
		if v, ok := args["channel"].(string); ok {
			opts.Channel = v
		}
		if v, ok := args["status"].(string); ok {
			opts.Status = v
		}
		if v, ok := args["start_time"].(string); ok {
			opts.StartTime = v
		}
		if v, ok := args["end_time"].(string); ok {
			opts.EndTime = v
		}
		if d, ok := args["page"].(float64); ok && d > 0 {
			opts.Page = int(d)
		}
		if d, ok := args["limit"].(float64); ok && d > 0 {
			opts.Limit = int(d)
		}

		return gw.ListConversations(ctx, apiKey, opts)
	})
}

func registerGetConversationMessages(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "get_conversation_messages",
		Description: "Get the full message history of a specific conversation (user queries and agent answers). Use this to analyze conversation quality, identify where the agent struggled, or find patterns in user questions.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"conversation_id": {Type: "string", Description: "Conversation ID to retrieve messages for"},
				"page":            {Type: "integer", Description: "Page number for pagination"},
				"limit":           {Type: "integer", Description: "Max messages per page"},
			},
			Required: []string{"conversation_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		conversationID, _ := args["conversation_id"].(string)
		if apiKey == "" || conversationID == "" {
			return nil, fmt.Errorf("api_key and conversation_id are required")
		}

		opts := gateway.ConversationMessagesOpts{}
		if d, ok := args["page"].(float64); ok && d > 0 {
			opts.Page = int(d)
		}
		if d, ok := args["limit"].(float64); ok && d > 0 {
			opts.Limit = int(d)
		}

		return gw.GetConversationMessages(ctx, apiKey, conversationID, opts)
	})
}

func registerGetConversation(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "get_conversation",
		Description: "Get details of a single conversation — status, channel, contact info, metadata, and timestamps. Use this before diving into messages to understand the conversation context.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"conversation_id": {Type: "string", Description: "Conversation ID"},
			},
			Required: []string{"conversation_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		cid, _ := args["conversation_id"].(string)
		if apiKey == "" || cid == "" {
			return nil, fmt.Errorf("api_key and conversation_id are required")
		}
		return gw.GetConversation(ctx, apiKey, cid)
	})
}

func registerGetConversationsBatch(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "get_conversations_batch",
		Description: "Fetch multiple conversations and their messages in a single call. Much faster than calling get_conversation + get_conversation_messages repeatedly. Use this when you need to inspect several conversations at once.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"conversation_ids":  {Type: "array", Description: "List of conversation IDs to fetch (max 20)"},
				"include_messages": {Type: "boolean", Description: "Whether to also fetch messages for each conversation (default true)"},
			},
			Required: []string{"conversation_ids"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		if apiKey == "" {
			return nil, fmt.Errorf("api_key is required")
		}

		rawIDs, ok := args["conversation_ids"].([]interface{})
		if !ok || len(rawIDs) == 0 {
			return nil, fmt.Errorf("conversation_ids must be a non-empty array of strings")
		}
		if len(rawIDs) > 20 {
			return nil, fmt.Errorf("conversation_ids limited to 20 at a time, got %d", len(rawIDs))
		}

		ids := make([]string, 0, len(rawIDs))
		for _, v := range rawIDs {
			if s, ok := v.(string); ok && s != "" {
				ids = append(ids, s)
			}
		}
		if len(ids) == 0 {
			return nil, fmt.Errorf("no valid conversation IDs provided")
		}

		includeMessages := true
		if v, ok := args["include_messages"].(bool); ok {
			includeMessages = v
		}

		return gw.GetConversationsBatch(ctx, apiKey, ids, includeMessages), nil
	})
}

func registerGetConversationContact(s *mcp.Server, gw *gateway.Client) {
	tool := mcp.Tool{
		Name:        "get_conversation_contact",
		Description: "Get the contact associated with a specific conversation — lead info, contact details, and metadata. Use this to see who participated in the conversation.",
		InputSchema: mcp.InputSchema{
			Type: "object",
			Properties: map[string]mcp.Property{
				"conversation_id": {Type: "string", Description: "Conversation ID"},
			},
			Required: []string{"conversation_id"},
		},
	}

	s.RegisterTool(tool, func(ctx context.Context, args map[string]interface{}) (interface{}, error) {
		apiKey := apiKeyFromArgs(args)
		cid, _ := args["conversation_id"].(string)
		if apiKey == "" || cid == "" {
			return nil, fmt.Errorf("api_key and conversation_id are required")
		}
		return gw.GetConversationContact(ctx, apiKey, cid)
	})
}
