package control

import "time"

type StepKind string

const (
	Task    StepKind = "task"
	Barrier StepKind = "barrier"
)

type ExecutionStatus string

const (
	ExecutionPending   ExecutionStatus = "pending"
	ExecutionRunning   ExecutionStatus = "running"
	ExecutionSucceeded ExecutionStatus = "succeeded"
	ExecutionFailed    ExecutionStatus = "failed"
	ExecutionUnknown   ExecutionStatus = "unknown"
)

type VerificationStatus string

const (
	VerificationNotChecked VerificationStatus = "not_checked"
	VerificationPassed     VerificationStatus = "passed"
	VerificationFailed     VerificationStatus = "failed"
)

type StepDefinition struct {
	Position        int      `json:"position"`
	Key             string   `json:"key"`
	Title           string   `json:"title"`
	Owner           string   `json:"owner"`
	Kind            StepKind `json:"kind"`
	Phase           string   `json:"phase"`
	Description     string   `json:"description"`
	DependsOn       []string `json:"depends_on"`
	Scope           []string `json:"scope"`
	MigratedRuntime bool     `json:"migrated_runtime"`
}

type StepState struct {
	Key             string             `json:"key"`
	Execution       ExecutionStatus    `json:"execution"`
	Verification    VerificationStatus `json:"verification"`
	AttemptCount    int                `json:"attempt_count"`
	ExternalRunID   string             `json:"external_run_id,omitempty"`
	LastSucceededAt *time.Time         `json:"last_execution_succeeded_at,omitempty"`
	LastVerifiedAt  *time.Time         `json:"last_output_verified_at,omitempty"`
	ObservedAt      *time.Time         `json:"observed_at,omitempty"`
	Error           string             `json:"error,omitempty"`
	Receipt         map[string]any     `json:"receipt,omitempty"`
	Action          StepAction         `json:"action"`
	BlockedBy       []string           `json:"blocked_by,omitempty"`
	Definition      StepDefinition     `json:"definition"`
}

type CloseRun struct {
	ID               string                `json:"id"`
	Profile          string                `json:"profile"`
	BillMonth        string                `json:"bill_month"`
	Mode             string                `json:"mode"`
	Status           string                `json:"status"`
	DefinitionHash   string                `json:"definition_hash"`
	SourceSHA        string                `json:"source_sha"`
	ParentCloseRunID string                `json:"parent_close_run_id,omitempty"`
	CreatedAt        time.Time             `json:"created_at"`
	UpdatedAt        time.Time             `json:"updated_at"`
	Steps            map[string]*StepState `json:"steps"`
}

type Attempt struct {
	ID             string             `json:"id"`
	CloseRunID     string             `json:"close_run_id"`
	StepKey        string             `json:"step_key"`
	AttemptNo      int                `json:"attempt_no"`
	Action         string             `json:"action"`
	Reason         string             `json:"reason"`
	IdempotencyKey string             `json:"idempotency_key"`
	Execution      ExecutionStatus    `json:"execution"`
	Verification   VerificationStatus `json:"verification"`
	StartedAt      time.Time          `json:"started_at"`
	FinishedAt     *time.Time         `json:"finished_at,omitempty"`
	Error          string             `json:"error,omitempty"`
	Receipt        map[string]any     `json:"receipt,omitempty"`
}

type Asset struct {
	Key                    string     `json:"key"`
	Label                  string     `json:"label"`
	BusinessPeriod         string     `json:"business_period"`
	Watermark              string     `json:"watermark,omitempty"`
	LastExecutionSucceeded *time.Time `json:"last_execution_succeeded_at,omitempty"`
	LastOutputVerified     *time.Time `json:"last_output_verified_at,omitempty"`
	Status                 string     `json:"status"`
	Owner                  string     `json:"owner"`
	PhysicalScope          []string   `json:"physical_scope"`
}

type StepAction struct {
	Type     string `json:"type"`
	Label    string `json:"label"`
	Enabled  bool   `json:"enabled"`
	Reason   string `json:"reason,omitempty"`
	ReadOnly bool   `json:"read_only,omitempty"`
}

type ActionRequest struct {
	Action string `json:"action" binding:"required"`
	Reason string `json:"reason" binding:"required"`
}

type RunnerResult struct {
	Verification  VerificationStatus `json:"verification"`
	ExternalRunID string             `json:"external_run_id,omitempty"`
	Receipt       map[string]any     `json:"receipt,omitempty"`
}

type DependencyObservation struct {
	Key                  string     `json:"key"`
	Label                string     `json:"label"`
	Status               string     `json:"status"`
	Message              string     `json:"message"`
	ObservedAt           *time.Time `json:"observed_at,omitempty"`
	CredentialConfigured bool       `json:"credential_configured"`
}

type CloseObservation struct {
	ObservedAt          time.Time               `json:"observed_at"`
	Close               *CloseRun               `json:"close"`
	Assets              []Asset                 `json:"assets"`
	Dependencies        []DependencyObservation `json:"dependencies"`
	NextGate            string                  `json:"next_gate"`
	WriteActionsEnabled bool                    `json:"write_actions_enabled"`
	WriteGate           string                  `json:"write_gate"`
	CredentialGaps      []string                `json:"credential_gaps"`
}
