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

package shared

import (
	"errors"
	"fmt"
	"slices"
	"strings"

	"git.secluded.site/go-lunatask"
	"github.com/modelcontextprotocol/go-sdk/mcp"
)

// ErrorResult creates an MCP CallToolResult indicating an error.
// Use this for user-facing errors (validation failures, API errors, etc.).
// The Go error return should remain nil per MCP SDK conventions.
func ErrorResult(msg string) *mcp.CallToolResult {
	return &mcp.CallToolResult{
		IsError: true,
		Content: []mcp.Content{
			&mcp.TextContent{Text: msg},
		},
	}
}

// Estimate constraints.
const (
	MinEstimate = 0
	MaxEstimate = 720
)

// ErrInvalidEstimate indicates the estimate is out of range.
var ErrInvalidEstimate = errors.New("estimate must be between 0 and 720 minutes")

// ErrInvalidStatusForWorkflow indicates the status is not valid for the area's workflow.
var ErrInvalidStatusForWorkflow = errors.New("invalid status for workflow")

// ValidateEstimate checks that an estimate is within the valid range (0-720 minutes).
func ValidateEstimate(estimate int) error {
	if estimate < MinEstimate || estimate > MaxEstimate {
		return fmt.Errorf("%w: got %d", ErrInvalidEstimate, estimate)
	}

	return nil
}

// ValidateStatusForWorkflow parses a status string and validates it's allowed for
// the given workflow. Returns the parsed status and nil on success, or an error
// with valid options on failure.
func ValidateStatusForWorkflow(
	input string,
	workflow lunatask.Workflow,
) (lunatask.TaskStatus, error) {
	status, err := lunatask.ParseTaskStatus(input)
	if err != nil {
		return "", fmt.Errorf(
			"%w: '%s' for %s; valid: %s",
			ErrInvalidStatusForWorkflow, input, workflow.Description(), formatValidStatuses(workflow),
		)
	}

	if !slices.Contains(workflow.ValidStatuses(), status) {
		return "", fmt.Errorf(
			"%w: '%s' not valid for %s; valid: %s",
			ErrInvalidStatusForWorkflow, input, workflow.Description(), formatValidStatuses(workflow),
		)
	}

	return status, nil
}

func formatValidStatuses(workflow lunatask.Workflow) string {
	statuses := workflow.ValidStatuses()
	strs := make([]string, len(statuses))

	for i, s := range statuses {
		strs[i] = string(s)
	}

	return strings.Join(strs, ", ")
}

// FormatAllStatuses returns a comma-separated list of all valid task statuses.
func FormatAllStatuses() string {
	statuses := lunatask.AllTaskStatuses()
	strs := make([]string, len(statuses))

	for i, s := range statuses {
		strs[i] = string(s)
	}

	return strings.Join(strs, ", ")
}
