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

package person

import (
	"context"
	"fmt"
	"strings"
	"time"

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

// ShowToolName is the name of the show person tool.
const ShowToolName = "show_person"

// ShowToolDescription describes the show person tool for LLMs.
const ShowToolDescription = `Shows metadata for a specific person from Lunatask.

Required:
- id: Person UUID or lunatask:// deep link

Note: Due to end-to-end encryption, person name is not available.
Only metadata (relationship strength, sources) is returned.`

// ShowInput is the input schema for showing a person.
type ShowInput struct {
	ID string `json:"id" jsonschema:"required"`
}

// ShowSource represents a source reference in the output.
type ShowSource struct {
	Source   string `json:"source"`
	SourceID string `json:"source_id"`
}

// ShowOutput is the output schema for showing a person.
type ShowOutput struct {
	DeepLink             string       `json:"deep_link"`
	RelationshipStrength *string      `json:"relationship_strength,omitempty"`
	Sources              []ShowSource `json:"sources,omitempty"`
	CreatedAt            string       `json:"created_at"`
	UpdatedAt            string       `json:"updated_at"`
}

// HandleShow shows a person's details.
func (h *Handler) HandleShow(
	ctx context.Context,
	_ *mcp.CallToolRequest,
	input ShowInput,
) (*mcp.CallToolResult, ShowOutput, error) {
	_, id, err := lunatask.ParseReference(input.ID)
	if err != nil {
		return shared.ErrorResult("invalid ID: expected UUID or lunatask:// deep link"), ShowOutput{}, nil
	}

	person, err := h.client.GetPerson(ctx, id)
	if err != nil {
		return shared.ErrorResult(err.Error()), ShowOutput{}, nil
	}

	output := buildShowOutput(person)
	text := formatPersonShowText(output)

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

func buildShowOutput(person *lunatask.Person) ShowOutput {
	output := ShowOutput{
		CreatedAt: person.CreatedAt.Format(time.RFC3339),
		UpdatedAt: person.UpdatedAt.Format(time.RFC3339),
	}

	output.DeepLink, _ = lunatask.BuildDeepLink(lunatask.ResourcePerson, person.ID)

	if person.RelationshipStrength != nil {
		s := string(*person.RelationshipStrength)
		output.RelationshipStrength = &s
	}

	if len(person.Sources) > 0 {
		output.Sources = make([]ShowSource, 0, len(person.Sources))
		for _, src := range person.Sources {
			output.Sources = append(output.Sources, ShowSource{
				Source:   src.Source,
				SourceID: src.SourceID,
			})
		}
	}

	return output
}

func formatPersonShowText(output ShowOutput) string {
	var builder strings.Builder

	builder.WriteString(fmt.Sprintf("Person: %s\n", output.DeepLink))

	if output.RelationshipStrength != nil {
		builder.WriteString(fmt.Sprintf("Relationship: %s\n", *output.RelationshipStrength))
	}

	if len(output.Sources) > 0 {
		builder.WriteString("Sources:\n")

		for _, src := range output.Sources {
			builder.WriteString(fmt.Sprintf("  - %s: %s\n", src.Source, src.SourceID))
		}
	}

	builder.WriteString(fmt.Sprintf("Created: %s\n", output.CreatedAt))
	builder.WriteString("Updated: " + output.UpdatedAt)

	return builder.String()
}
