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

// Package timeline provides the MCP tool for adding timeline notes to people.
package timeline

import (
	"context"

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

// ToolName is the name of the add timeline note tool.
const ToolName = "add_timeline_note"

// ToolDescription describes the add timeline note tool for LLMs.
const ToolDescription = `Add a note to a person's memory timeline.

Append-only—each call creates a new timeline entry. Great for tracking
interactions, meetings, or memorable moments with someone.`

// ToolAnnotations returns hints about tool behavior.
func ToolAnnotations() *mcp.ToolAnnotations {
	return &mcp.ToolAnnotations{
		DestructiveHint: ptr(false),
		OpenWorldHint:   ptr(true),
		Title:           "Add timeline note",
	}
}

func ptr[T any](v T) *T { return &v }

// Input is the input schema for adding a timeline note.
type Input struct {
	PersonID string  `json:"person_id"         jsonschema:"Person UUID or lunatask:// deep link"`
	Content  *string `json:"content,omitempty" jsonschema:"Markdown content describing the interaction"`
	Date     *string `json:"date,omitempty"    jsonschema:"Date of interaction (strtotime syntax, default: today)"`
}

// Output is the output schema for adding a timeline note.
type Output struct {
	Success        bool   `json:"success"`
	PersonDeepLink string `json:"person_deep_link"`
	NoteID         string `json:"note_id"`
}

// Handler handles timeline note MCP tool requests.
type Handler struct {
	client *lunatask.Client
}

// NewHandler creates a new timeline handler.
func NewHandler(accessToken string) *Handler {
	return &Handler{
		client: lunatask.NewClient(accessToken, lunatask.UserAgent("lune-mcp/1.0")),
	}
}

// Handle adds a timeline note to a person.
func (h *Handler) Handle(
	ctx context.Context,
	_ *mcp.CallToolRequest,
	input Input,
) (*mcp.CallToolResult, Output, error) {
	_, personID, err := lunatask.ParseReference(input.PersonID)
	if err != nil {
		return shared.ErrorResult("invalid person_id: expected UUID or lunatask:// deep link"),
			Output{}, nil
	}

	builder := h.client.NewTimelineNote(personID)

	if input.Content != nil {
		builder.WithContent(*input.Content)
	}

	if input.Date != nil {
		date, err := dateutil.Parse(*input.Date)
		if err != nil {
			return shared.ErrorResult(err.Error()), Output{}, nil
		}

		builder.OnDate(date)
	}

	note, err := builder.Create(ctx)
	if err != nil {
		return shared.ErrorResult(err.Error()), Output{}, nil
	}

	personDeepLink, _ := lunatask.BuildDeepLink(lunatask.ResourcePerson, personID)

	dateStr := "today"

	if input.Date != nil {
		date, _ := dateutil.Parse(*input.Date)
		dateStr = date.Format("2006-01-02")
	}

	return &mcp.CallToolResult{
			Content: []mcp.Content{&mcp.TextContent{
				Text: "Timeline note added for " + personDeepLink + " on " + dateStr,
			}},
		}, Output{
			Success:        true,
			PersonDeepLink: personDeepLink,
			NoteID:         note.ID,
		}, nil
}
