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

package journal

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"
	"github.com/spf13/cobra"
)

// AddCmd creates a journal entry. Exported for use by the jrnl shortcut.
var AddCmd = &cobra.Command{
	Use:   "add [CONTENT]",
	Short: "Create a journal entry",
	Long: `Create a journal entry in Lunatask.

Creates an entry for today by default. Use --date to specify another date
using natural language (e.g., "yesterday", "last friday", "2024-01-15").

Content supports Markdown formatting for rich text entries.
Use "-" as CONTENT to read from stdin (useful for piping or multi-line input).`,
	RunE: runAdd,
}

func init() {
	AddCmd.Flags().StringP("date", "d", "", "Entry date (natural language, default: today)")
	AddCmd.Flags().StringP("name", "n", "", "Entry title (omit to use weekday name)")
}

func runAdd(cmd *cobra.Command, args []string) error {
	date, err := dateutil.Parse(cmd.Flag("date").Value.String())
	if err != nil {
		return err
	}

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

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

	builder := apiClient.NewJournalEntry(date)

	if content != "" {
		builder.WithContent(content)
	}

	if name := cmd.Flag("name").Value.String(); name != "" {
		builder.WithName(name)
	}

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

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

	return nil
}

func resolveContent(args []string) (string, error) {
	if len(args) == 0 {
		return "", nil
	}

	if args[0] != "-" {
		return strings.Join(args, " "), nil
	}

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

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