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

package habit

import (
	"errors"
	"fmt"

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

// ErrUnknownHabit indicates the specified habit key was not found in config.
var ErrUnknownHabit = errors.New("unknown habit key")

// TrackCmd tracks a habit activity. Exported for potential use by shortcuts.
var TrackCmd = &cobra.Command{
	Use:   "track KEY",
	Short: "Track a habit",
	Long: `Record that a habit was performed.

KEY is the habit key from your config (not the raw Lunatask ID).
Tracks for today by default. Use --date to specify another date
using strtotime syntax (e.g., "yesterday", "-2 days", "next Monday").`,
	Args:              cobra.ExactArgs(1),
	ValidArgsFunction: completion.Habits,
	RunE:              runTrack,
}

func init() {
	TrackCmd.Flags().StringP("date", "d", "", "Date performed (default: today)")
}

func runTrack(cmd *cobra.Command, args []string) error {
	habitKey := args[0]

	cfg, err := config.Load()
	if err != nil {
		return err
	}

	habit := cfg.HabitByKey(habitKey)
	if habit == nil {
		return fmt.Errorf("%w: %s", ErrUnknownHabit, habitKey)
	}

	date, err := resolveDate(cmd)
	if err != nil {
		return err
	}

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

	req := &lunatask.TrackHabitActivityRequest{PerformedOn: date}

	if err := ui.SpinVoid("Tracking habit…", func() error {
		_, err := apiClient.TrackHabitActivity(cmd.Context(), habit.ID, req)

		return err
	}); err != nil {
		return err
	}

	fmt.Fprintf(cmd.OutOrStdout(), "%s\n",
		ui.Success.Render("Tracked "+habit.Name+" for "+date.String()))

	return nil
}

func resolveDate(cmd *cobra.Command) (lunatask.Date, error) {
	dateStr, _ := cmd.Flags().GetString("date")

	return dateutil.Parse(dateStr)
}
