package mcp

import (
	"fmt"

	"github.com/tidbcloud/AgentTeam/desktop/internal/types"
	"github.com/tidbcloud/AgentTeam/desktop/internal/wire/apiclient"
)

func messageMCPTools(h *mcpHandler) []mcpToolRegistration {
	return []mcpToolRegistration{
		sendMessageMCPTool(h),
		readHistoryMCPTool(h),
		searchMessagesMCPTool(h),
		uploadFileMCPTool(h),
		viewFileMCPTool(h),
		setReactionMCPTool(h),
		getReactionsMCPTool(h),
	}
}

func sendMessageMCPTool(h *mcpHandler) mcpToolRegistration {
	return agentMCPTool(
		types.MCPToolDef{
			Name:        "message_send",
			Description: "Post text or attachments to an exact target. Defaults to the current active delivery targets; other destinations require allow_cross_target. Plain or final output is not posted.",
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"target": {
						Type:        "string",
						Description: "Exact destination copied from the current delivery, or a proactive destination with allow_cross_target.",
					},
					"content": {
						Type:        "string",
						Description: "Complete message. Mention agents as `[@name](/mentions/agent/<agent-id>)`; plain `@name` may be ambiguous.",
					},
					"file_paths": {
						Type:        "array",
						Description: "Local files to attach.",
						Items:       &types.MCPProperty{Type: "string"},
					},
					"attachment_ids": {
						Type:        "array",
						Description: "IDs returned by the attachment-upload tool.",
						Items:       &types.MCPProperty{Type: "string"},
					},
					"team_invoke_team_id": {
						Type:        "string",
						Description: "Only for Team-member mentions needing hidden Team Context; omit for ordinary direct mentions.",
					},
					"allow_cross_target": {
						Type:        "boolean",
						Description: "Opt in to send beyond the active delivery targets; only for intentional proactive sends.",
					},
				},
				Required:             []string{"target", "content"},
				AdditionalProperties: types.MCPDisallowAdditionalProperties(),
			},
		},
		h.toolSendMessage,
	)
}

func readHistoryMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_history_read",
			Description: "Read history for an exact AgentTeam target.",
			Annotations: &types.MCPToolAnnotation{ReadOnlyHint: true},
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"target": {Type: "string", Description: "Channel, DM, thread, #tsk_xxx, or #team_xxxxxxxxxxxxxx target."},
					"limit":  {Type: "number", Description: "1-100; default 20."},
					"before": {Type: "number", Description: "Return seq below this value."},
					"after":  {Type: "number", Description: "Return seq above this value."},
				},
				Required: []string{"target"},
			},
		},
		h.toolReadHistory,
	)
}

func setReactionMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_reaction_set",
			Description: "Add or remove your reaction on a posted message.",
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"message_id": {Type: "string", Description: "The target full message ID or unambiguous 8-character message ID prefix."},
					"emoji":      {Type: "string", Description: "Emoji character or shortcode, e.g. '👍', '❌', '🎉'."},
					"op":         {Type: "string", Description: "Reaction operation.", Enum: []any{"add", "remove"}},
				},
				Required: []string{"message_id", "emoji", "op"},
			},
		},
		h.toolSetReaction,
	)
}

func getReactionsMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_reaction_list",
			Description: "Get reaction counts for a posted message.",
			Annotations: &types.MCPToolAnnotation{ReadOnlyHint: true},
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"message_id": {Type: "string", Description: "The target full message ID or unambiguous 8-character message ID prefix."},
				},
				Required: []string{"message_id"},
			},
		},
		h.toolGetReactions,
	)
}

func uploadFileMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_attachment_upload",
			Description: fmt.Sprintf("Upload a file to attach to a message. Returns an attachment ID that you can pass to the send tool's attachment_ids parameter. Max size: %s.", apiclient.MaxUploadSizeLabel),
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"file_path": {Type: "string", Description: "Absolute path to the file on your local filesystem"},
					"channel":   {Type: "string", Description: "Target where this file will be used."},
				},
				Required: []string{"file_path", "channel"},
			},
		},
		h.toolUploadFile,
	)
}

func viewFileMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_attachment_view",
			Description: "Download an attachment to a local path; contents are not inlined.",
			Annotations: &types.MCPToolAnnotation{ReadOnlyHint: true},
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"attachment_id": {Type: "string", Description: "The attachment ID to download"},
				},
				Required: []string{"attachment_id"},
			},
		},
		h.toolViewFile,
	)
}

func searchMessagesMCPTool(h *mcpHandler) mcpToolRegistration {
	return apiMCPTool(h,
		types.MCPToolDef{
			Name:        "message_search",
			Description: "Search accessible AgentTeam messages with context.",
			Annotations: &types.MCPToolAnnotation{ReadOnlyHint: true},
			InputSchema: types.MCPInputSchema{
				Type: "object",
				Properties: map[string]types.MCPProperty{
					"q":       {Type: "string", Description: "Search query (keywords)"},
					"channel": {Type: "string", Description: "Optional target scope filter."},
					"target":  {Type: "string", Description: "Alias for channel; supports the same target formats."},
					"limit":   {Type: "number", Description: "Max results to return (default 20, max 50)"},
					"before":  {Type: "number", Description: "Return matches below this seq; requires scope."},
				},
				Required: []string{"q"},
			},
		},
		h.toolSearchMessages,
	)
}
