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

package lunatask

import (
	"context"
	"fmt"
	"net/http"
	"time"
)

// PersonTimelineNote is a note on a person's memory timeline.
// Content is encrypted client-side and will be null when read.
type PersonTimelineNote struct {
	ID        string    `json:"id"`
	DateOn    *Date     `json:"date_on"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

// createPersonTimelineNoteRequest defines a timeline note for JSON serialization.
type createPersonTimelineNoteRequest struct {
	// PersonID is the ID of the person to add the note to (required).
	PersonID string `json:"person_id"`
	// DateOn is the date for the note (optional, defaults to today).
	DateOn *Date `json:"date_on,omitempty"`
	// Content is the Markdown content of the note (optional but impractical if empty).
	Content *string `json:"content,omitempty"`
}

// personTimelineNoteResponse wraps a single timeline note from the API.
type personTimelineNoteResponse struct {
	PersonTimelineNote PersonTimelineNote `json:"person_timeline_note"`
}

// TimelineNoteBuilder constructs and creates a timeline note via method chaining.
// Content is encrypted client-side; the API accepts it on create but returns null on read.
//
//	note, err := client.NewTimelineNote(personID).
//		OnDate(lunatask.Today()).
//		WithContent("Had coffee, discussed the project.").
//		Create(ctx)
type TimelineNoteBuilder struct {
	client *Client
	req    createPersonTimelineNoteRequest
}

// NewTimelineNote starts building a timeline note for the given person.
// Get person IDs from [Client.ListPeople].
func (c *Client) NewTimelineNote(personID string) *TimelineNoteBuilder {
	return &TimelineNoteBuilder{client: c, req: createPersonTimelineNoteRequest{PersonID: personID}}
}

// OnDate sets when this interaction occurred.
func (b *TimelineNoteBuilder) OnDate(date Date) *TimelineNoteBuilder {
	b.req.DateOn = &date

	return b
}

// WithContent sets the Markdown body describing the interaction.
func (b *TimelineNoteBuilder) WithContent(content string) *TimelineNoteBuilder {
	b.req.Content = &content

	return b
}

// Create sends the timeline note to Lunatask.
// Get person IDs from [Client.ListPeople].
func (b *TimelineNoteBuilder) Create(ctx context.Context) (*PersonTimelineNote, error) {
	if b.req.PersonID == "" {
		return nil, fmt.Errorf("%w: person_id is required", ErrBadRequest)
	}

	resp, _, err := doJSON[personTimelineNoteResponse](ctx, b.client, http.MethodPost, "/person_timeline_notes", b.req)
	if err != nil {
		return nil, err
	}

	return &resp.PersonTimelineNote, nil
}
