package tools

import (
	"context"
	"strings"

	"github.com/modelcontextprotocol/go-sdk/mcp"

	"git.warky.dev/wdevs/amcs/internal/store"
)

// ToolEntry describes a single registered MCP tool.
type ToolEntry struct {
	Name        string
	Description string
	Category    string
}

// DescribeTool implements the describe_tools and annotate_tool MCP tools.
type DescribeTool struct {
	store   *store.DB
	catalog []ToolEntry
}

func NewDescribeTool(db *store.DB, catalog []ToolEntry) *DescribeTool {
	return &DescribeTool{store: db, catalog: catalog}
}

// describe_tools

type DescribeToolsInput struct {
	Category string `json:"category,omitempty" jsonschema:"filter results to a single category (e.g. thoughts, projects, files, skills, chat, meta)"`
}

type AnnotatedToolEntry struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Category    string `json:"category"`
	Notes       string `json:"notes,omitempty"`
}

type DescribeToolsOutput struct {
	Tools []AnnotatedToolEntry `json:"tools"`
}

func (t *DescribeTool) Describe(ctx context.Context, _ *mcp.CallToolRequest, in DescribeToolsInput) (*mcp.CallToolResult, DescribeToolsOutput, error) {
	annotations, err := t.store.GetToolAnnotations(ctx)
	if err != nil {
		return nil, DescribeToolsOutput{}, err
	}

	cat := strings.TrimSpace(strings.ToLower(in.Category))

	entries := make([]AnnotatedToolEntry, 0, len(t.catalog))
	for _, e := range t.catalog {
		if cat != "" && e.Category != cat {
			continue
		}
		entries = append(entries, AnnotatedToolEntry{
			Name:        e.Name,
			Description: e.Description,
			Category:    e.Category,
			Notes:       annotations[e.Name],
		})
	}

	return nil, DescribeToolsOutput{Tools: entries}, nil
}

// annotate_tool

type AnnotateToolInput struct {
	ToolName string `json:"tool_name" jsonschema:"the exact name of the tool to annotate"`
	Notes    string `json:"notes" jsonschema:"your usage notes, reminders, or gotchas for this tool; pass empty string to clear"`
}

type AnnotateToolOutput struct {
	ToolName string `json:"tool_name"`
}

func (t *DescribeTool) Annotate(ctx context.Context, _ *mcp.CallToolRequest, in AnnotateToolInput) (*mcp.CallToolResult, AnnotateToolOutput, error) {
	if strings.TrimSpace(in.ToolName) == "" {
		return nil, AnnotateToolOutput{}, errRequiredField("tool_name")
	}
	if err := t.store.UpsertToolAnnotation(ctx, in.ToolName, in.Notes); err != nil {
		return nil, AnnotateToolOutput{}, err
	}
	return nil, AnnotateToolOutput{ToolName: in.ToolName}, nil
}
