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

package person

import (
	"fmt"
	"os"
	"strings"

	"git.secluded.site/go-lunatask"
	"git.secluded.site/lune/internal/client"
	"git.secluded.site/lune/internal/dateutil"
	"git.secluded.site/lune/internal/ui"
	"git.secluded.site/lune/internal/validate"
	"github.com/spf13/cobra"
)

// TimelineCmd adds a timeline note to a person. Exported for potential use by shortcuts.
var TimelineCmd = &cobra.Command{
	Use:   "timeline ID",
	Short: "Add a timeline note",
	Long: `Add a timeline note to a person's memory timeline.

Use "-" as content flag value to read from stdin.`,
	Args: cobra.ExactArgs(1),
	RunE: runTimeline,
}

func init() {
	TimelineCmd.Flags().StringP("content", "c", "", "Note content (use - for stdin)")
	TimelineCmd.Flags().StringP("date", "d", "", "Date of interaction (natural language)")
}

func runTimeline(cmd *cobra.Command, args []string) error {
	personID, err := validate.Reference(args[0])
	if err != nil {
		return err
	}

	apiClient, err := client.New()
	if err != nil {
		return err
	}

	builder := apiClient.NewTimelineNote(personID)

	if err := applyTimelineContent(cmd, builder); err != nil {
		return err
	}

	if err := applyTimelineDate(cmd, builder); err != nil {
		return err
	}

	note, err := ui.Spin("Creating timeline note…", func() (*lunatask.PersonTimelineNote, error) {
		return builder.Create(cmd.Context())
	})
	if err != nil {
		return err
	}

	fmt.Fprintln(cmd.OutOrStdout(), ui.Success.Render("Created timeline note: "+note.ID))

	return nil
}

func applyTimelineContent(cmd *cobra.Command, builder *lunatask.TimelineNoteBuilder) error {
	content, _ := cmd.Flags().GetString("content")
	if content == "" {
		return nil
	}

	resolved, err := resolveContent(content)
	if err != nil {
		return err
	}

	builder.WithContent(resolved)

	return nil
}

func resolveContent(content string) (string, error) {
	if content != "-" {
		return content, nil
	}

	data, err := os.ReadFile("/dev/stdin")
	if err != nil {
		return "", fmt.Errorf("reading stdin: %w", err)
	}

	return strings.TrimSpace(string(data)), nil
}

func applyTimelineDate(cmd *cobra.Command, builder *lunatask.TimelineNoteBuilder) error {
	dateStr, _ := cmd.Flags().GetString("date")
	if dateStr == "" {
		return nil
	}

	date, err := dateutil.Parse(dateStr)
	if err != nil {
		return err
	}

	builder.OnDate(date)

	return nil
}
