// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package person

import (
	"context"
	"fmt"
	"strings"

	"git.secluded.site/go-lunatask"
	"git.secluded.site/lune/internal/mcp/shared"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

// ListToolName is the name of the list people tool.
const ListToolName = "list_people"

// ListToolDescription describes the list people tool for LLMs.
const ListToolDescription = `Lists people from Lunatask's relationship tracker.

Optional:
- source: Filter by source identifier
- source_id: Filter by source-specific ID

Returns person metadata (IDs, relationship strength, created dates).
Use lunatask://person/{id} resource for full person details.

Note: Due to end-to-end encryption, names are not available
in the list — only metadata is returned.`

// ListInput is the input schema for listing people.
type ListInput struct {
	Source   *string `json:"source,omitempty"`
	SourceID *string `json:"source_id,omitempty"`
}

// ListPersonItem represents a person in the list output.
type ListPersonItem struct {
	DeepLink             string  `json:"deep_link"`
	RelationshipStrength *string `json:"relationship_strength,omitempty"`
	CreatedAt            string  `json:"created_at"`
}

// ListOutput is the output schema for listing people.
type ListOutput struct {
	People []ListPersonItem `json:"people"`
	Count  int              `json:"count"`
}

// HandleList lists people.
func (h *Handler) HandleList(
	ctx context.Context,
	_ *mcp.CallToolRequest,
	input ListInput,
) (*mcp.CallToolResult, ListOutput, error) {
	opts := buildListOptions(input)

	people, err := h.client.ListPeople(ctx, opts)
	if err != nil {
		return shared.ErrorResult(err.Error()), ListOutput{}, nil
	}

	items := make([]ListPersonItem, 0, len(people))

	for _, person := range people {
		deepLink, _ := lunatask.BuildDeepLink(lunatask.ResourcePerson, person.ID)

		item := ListPersonItem{
			DeepLink:  deepLink,
			CreatedAt: person.CreatedAt.Format("2006-01-02"),
		}

		if person.RelationshipStrength != nil {
			rel := string(*person.RelationshipStrength)
			item.RelationshipStrength = &rel
		}

		items = append(items, item)
	}

	output := ListOutput{
		People: items,
		Count:  len(items),
	}

	text := formatListText(items)

	return &mcp.CallToolResult{
		Content: []mcp.Content{&mcp.TextContent{Text: text}},
	}, output, nil
}

func buildListOptions(input ListInput) *lunatask.ListPeopleOptions {
	if input.Source == nil && input.SourceID == nil {
		return nil
	}

	opts := &lunatask.ListPeopleOptions{}

	if input.Source != nil {
		opts.Source = input.Source
	}

	if input.SourceID != nil {
		opts.SourceID = input.SourceID
	}

	return opts
}

func formatListText(items []ListPersonItem) string {
	if len(items) == 0 {
		return "No people found"
	}

	var text strings.Builder

	text.WriteString(fmt.Sprintf("Found %d person(s):\n", len(items)))

	for _, item := range items {
		text.WriteString("- ")
		text.WriteString(item.DeepLink)

		if item.RelationshipStrength != nil {
			text.WriteString(" (")
			text.WriteString(*item.RelationshipStrength)
			text.WriteString(")")
		}

		text.WriteString("\n")
	}

	text.WriteString("\nUse lunatask://person/{id} resource for full details.")

	return text.String()
}
