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

package lunatask

import (
	"errors"
	"fmt"
	"strings"
)

// Workflow represents an area's task management workflow.
type Workflow string

// Valid workflow values.
const (
	WorkflowPriorityList   Workflow = "priority_list"
	WorkflowNowLater       Workflow = "now_later"
	WorkflowKanban         Workflow = "kanban"
	WorkflowPlanYourDays   Workflow = "plan_your_days"
	WorkflowMustShouldWant Workflow = "must_should_want"
	WorkflowEisenhower     Workflow = "eisenhower"
)

// Errors returned by Workflow operations.
var (
	// ErrInvalidWorkflow is returned when parsing an unknown workflow string.
	ErrInvalidWorkflow = errors.New("invalid workflow")
)

// String returns the workflow value as a string.
func (w Workflow) String() string {
	return string(w)
}

// ValidStatuses returns the task statuses that apply to this workflow.
func (w Workflow) ValidStatuses() []TaskStatus {
	switch w {
	case WorkflowPriorityList:
		return nil
	case WorkflowNowLater:
		return []TaskStatus{StatusLater, StatusInProgress, StatusCompleted}
	case WorkflowKanban:
		return []TaskStatus{StatusLater, StatusNext, StatusInProgress, StatusWaiting, StatusCompleted}
	case WorkflowPlanYourDays:
		return []TaskStatus{StatusCompleted}
	case WorkflowMustShouldWant:
		return []TaskStatus{StatusCompleted}
	case WorkflowEisenhower:
		return []TaskStatus{StatusCompleted}
	default:
		return nil
	}
}

// UsesMotivation reports whether this workflow uses the motivation field (must/should/want).
func (w Workflow) UsesMotivation() bool {
	return w == WorkflowMustShouldWant
}

// UsesEisenhower reports whether this workflow uses the important/urgent fields.
func (w Workflow) UsesEisenhower() bool {
	return w == WorkflowEisenhower
}

// UsesScheduling reports whether this workflow is date-oriented (scheduled_on).
func (w Workflow) UsesScheduling() bool {
	return w == WorkflowPlanYourDays
}

// UsesPriority reports whether this workflow uses only priority (no status columns).
func (w Workflow) UsesPriority() bool {
	return w == WorkflowPriorityList
}

// Description returns a human-readable description of the workflow for LLMs.
func (w Workflow) Description() string {
	switch w {
	case WorkflowPriorityList:
		return "Priority-only workflow. Tasks are ranked by priority (lowest to highest) without status columns."
	case WorkflowNowLater:
		return "Simple two-column workflow. Tasks are either 'later' or 'in-progress', then marked 'completed'."
	case WorkflowKanban:
		return "Full kanban board with columns: later, next, in-progress, waiting, completed."
	case WorkflowPlanYourDays:
		return "Date-oriented workflow. Tasks are scheduled for specific days using the scheduled_on field."
	case WorkflowMustShouldWant:
		return "Motivation-based workflow. Tasks are categorized as 'must', 'should', or 'want' to clarify why they matter."
	case WorkflowEisenhower:
		return "Eisenhower matrix workflow. Tasks are categorized by 'important' and 'urgent' flags into four quadrants."
	default:
		return fmt.Sprintf("Unknown workflow: %s", w)
	}
}

// ParseWorkflow parses a string to a Workflow value (case-insensitive).
// Accepts both snake_case (priority_list) and kebab-case (priority-list).
func ParseWorkflow(str string) (Workflow, error) {
	normalized := strings.ToLower(strings.ReplaceAll(str, "-", "_"))
	switch normalized {
	case "priority_list":
		return WorkflowPriorityList, nil
	case "now_later":
		return WorkflowNowLater, nil
	case "kanban":
		return WorkflowKanban, nil
	case "plan_your_days":
		return WorkflowPlanYourDays, nil
	case "must_should_want":
		return WorkflowMustShouldWant, nil
	case "eisenhower":
		return WorkflowEisenhower, nil
	default:
		return "", fmt.Errorf("%w: %q", ErrInvalidWorkflow, str)
	}
}

// Workflows returns all valid workflow values.
func Workflows() []Workflow {
	return []Workflow{
		WorkflowPriorityList,
		WorkflowNowLater,
		WorkflowKanban,
		WorkflowPlanYourDays,
		WorkflowMustShouldWant,
		WorkflowEisenhower,
	}
}
