package statemachine

import "time"

// ModelSpec defines LLM model configuration.
type ModelSpec struct {
	ModelID  string // e.g. "claude-opus-5", "claude-sonnet-5"
	Thinking string // "adaptive" or ""
	Effort   string // "low", "medium", "high", "xhigh", "max"
}

// PromptSpec defines a prompt template with variables and model.
type PromptSpec struct {
	TemplateRef string            // e.g. "planner/default.tmpl"
	RawTemplate string            // overrides TemplateRef if non-empty
	Variables   map[string]any    // template variables
	Model       ModelSpec         // which LLM to use
	LessonsRef  string            // key into lessons store
}

// PiRetryPolicy defines retry and timeout settings for Pi command execution.
type PiRetryPolicy struct {
	ScheduleToCloseTimeout time.Duration // default: 5m
	InitialInterval        time.Duration // default: 2s
	MaximumInterval        time.Duration // default: 30s
	BackoffCoefficient     float64       // default: 2.0
	StreamTimeout          time.Duration // default: 30s
	StreamTimeoutMax       time.Duration // default: 2m
}

// ActivityTuning defines timeouts and retry counts for activities.
type ActivityTuning struct {
	ImplementerBaseTimeout time.Duration // default: 10m
	ImplementerMaxRetries  int           // default: 3
	JudgeTimeout           time.Duration // default: 5m
	PiRetry                PiRetryPolicy
	// Retry policy settings
	InitialRetryInterval   time.Duration // default: 2s
	MaxRetryInterval       time.Duration // default: 5m
	RetryBackoffCoefficient float64      // default: 2.0
}

// OrchestratorConfig holds all runtime configuration for the orchestrator.
type OrchestratorConfig struct {
	SystemPrompt string                    // shared prompt prefix
	Skills       []SkillRef                // required skill sources
	RolePrompts  map[string]PromptSpec     // per-role: "planner", "judge", "implementer"
	Tuning       ActivityTuning
}

// OrchestratorInput is the input to the Orchestrator workflow.
type OrchestratorInput struct {
	TargetRepoPath      string
	RemoteURL           string
	Milestone           string // e.g. "T0"
	Config              OrchestratorConfig
	DryRun              bool
	CycleCount          int
	MaxCyclesBeforeCAN  int // default: 100
	PiProvider          string // pi provider name (e.g., "local-llm"); required for skill preparation
}

// OrchestratorOutput is the output of the Orchestrator workflow.
type OrchestratorOutput struct {
	MilestoneComplete bool
	Done              bool
	LastError         string
}

// TaskUnitInput is the input to the TaskUnit workflow.
type TaskUnitInput struct {
	TaskID         string
	RemoteURL      string
	TargetRepoPath string
	Milestone      string
	Config         OrchestratorConfig
	DryRun         bool
}

// TaskUnitOutput is the output of the TaskUnit workflow.
type TaskUnitOutput struct {
	TaskID   string
	Status   string // "success" or "failed"
	Verdict  string // "pass" or "fail" from judge
	Critique string // feedback from judge
	Branch   string
	Reason   string // error reason if failed
	Changes  string // summary of changes
}

// SkillRef references a skill source.
type SkillRef struct {
	Name string // skill identifier
	URL  string // source to clone
}

// Default values for types.
const (
	defaultScheduleToCloseTimeout = 5 * time.Minute
	defaultInitialInterval         = 2 * time.Second
	defaultMaximumInterval         = 30 * time.Second
	defaultBackoffCoefficient      = 2.0
	defaultStreamTimeout           = 30 * time.Second
	defaultStreamTimeoutMax        = 2 * time.Minute
	defaultImplementerBaseTimeout  = 10 * time.Minute
	defaultImplementerMaxRetries   = 3
	defaultJudgeTimeout            = 5 * time.Minute
)

// NewPiRetryPolicy returns a PiRetryPolicy with defaults.
func NewPiRetryPolicy() PiRetryPolicy {
	return PiRetryPolicy{
		ScheduleToCloseTimeout: defaultScheduleToCloseTimeout,
		InitialInterval:        defaultInitialInterval,
		MaximumInterval:        defaultMaximumInterval,
		BackoffCoefficient:     defaultBackoffCoefficient,
		StreamTimeout:          defaultStreamTimeout,
		StreamTimeoutMax:       defaultStreamTimeoutMax,
	}
}

// NewActivityTuning returns an ActivityTuning with defaults.
func NewActivityTuning() ActivityTuning {
	return ActivityTuning{
		ImplementerBaseTimeout: defaultImplementerBaseTimeout,
		ImplementerMaxRetries:  defaultImplementerMaxRetries,
		JudgeTimeout:           defaultJudgeTimeout,
		PiRetry:                NewPiRetryPolicy(),
	}
}

// PromptUpdate represents an update to a role prompt.
type PromptUpdate struct {
	Role string
	Spec PromptSpec
}
