/**
 * FlowEngine Types
 *
 * Defines types for SANDCODE Flow: the self-improving autonomous development engine.
 *
 * Flow lifecycle: Intent -> Spec -> Plan -> Implement -> Verify -> Fix -> Checkpoint
 *
 * Persisted in .sandcode/flow.json (active state) and .sandcode/checkpoints/ (snapshots).
 */

/** Unique identifier for flows, specs, plans, and checkpoints */
export type FlowId = string & { readonly __brand: unique symbol }
export type SpecId = string & { readonly __brand: unique symbol }
export type PlanId = string & { readonly __brand: unique symbol }
export type CheckpointId = string & { readonly __brand: unique symbol }

/** Create a flow-scoped ID */
export function createFlowId(): FlowId {
  return `flow_${Date.now()}_${Math.random().toString(36).slice(2, 8)}` as FlowId
}

export function createSpecId(flowId: FlowId): SpecId {
  return `spec_${flowId}` as SpecId
}

export function createPlanId(flowId: FlowId): PlanId {
  return `plan_${flowId}` as PlanId
}

export function createCheckpointId(stepIndex: number): CheckpointId {
  return `ckpt_${stepIndex}_${Date.now()}` as CheckpointId
}

/** Overall flow status */
export type FlowStatus =
  | 'intent-captured'
  | 'spec-generating'
  | 'spec-pending-approval'
  | 'plan-decomposing'
  | 'executing'
  | 'step-failed'
  | 'paused'
  | 'completed'
  | 'cancelled'
  | 'escalated'

/** Individual step status within a plan */
export type StepStatus =
  | 'pending'
  | 'in-progress'
  | 'verifying'
  | 'fixing'
  | 'completed'
  | 'failed'
  | 'skipped'
  | 'escalated'

/** The type of task the flow is performing */
export type FlowType = 'feature' | 'bugfix' | 'refactor' | 'optimization' | 'test' | 'unknown'

/** Risk level for a spec */
export type RiskLevel = 'low' | 'medium' | 'high'

/** A single acceptance criterion for a spec */
export interface AcceptanceCriterion {
  /** Description of what should be true */
  description: string
  /** How to verify this criterion */
  verificationMethod: string
  /** Whether this criterion has been met */
  met: boolean
}

/** A generated specification for the flow */
export interface FlowSpec {
  /** Unique spec ID */
  id: SpecId
  /** Parent flow ID */
  flowId: FlowId
  /** What the user wants (original intent) */
  intent: string
  /** Type of task */
  type: FlowType
  /** Estimated scope */
  scope: {
    /** Estimated number of files to change */
    estimatedFiles: number
    /** Modules likely affected */
    modules: string[]
  }
  /** Functional requirements */
  requirements: string[]
  /** Concrete acceptance criteria */
  acceptanceCriteria: AcceptanceCriterion[]
  /** Edge cases identified */
  edgeCases: string[]
  /** Files that will be touched */
  affectedFiles: string[]
  /** Dependencies between changes */
  dependencies: string[]
  /** Risk assessment */
  risk: RiskLevel
  /** Constraints from the user */
  constraints: string[]
  /** When the spec was generated */
  createdAt: number
  /** When the user approved it (if approved) */
  approvedAt?: number
}

/** A single step in a plan */
export interface PlanStep {
  /** Step index (0-based) */
  index: number
  /** What this step does */
  description: string
  /** Files to modify */
  files: string[]
  /** Pass/fail criteria */
  passCriteria: string[]
  /** Indices of steps that must complete before this one */
  dependsOn: number[]
  /** Current status */
  status: StepStatus
  /** Number of verify-fix iterations so far */
  iterations: number
  /** Max iterations before escalation */
  maxIterations: number
  /** Error from last failure (if any) */
  lastError?: string
  /** Files changed during this step */
  changedFiles: string[]
  /** Test results from verification */
  testResults?: TestResults
}

/** Test results from the Forge */
export interface TestResults {
  /** Whether all tests passed */
  passed: boolean
  /** Total tests run */
  total: number
  /** Number that passed */
  passedCount: number
  /** Number that failed */
  failedCount: number
  /** Error output (if any) */
  errors: string[]
  /** How long the tests took */
  duration: number
  /** Timestamp of the run */
  timestamp: number
}

/** A decomposed plan */
export interface FlowPlan {
  /** Unique plan ID */
  id: PlanId
  /** Parent flow ID */
  flowId: FlowId
  /** Parent spec ID */
  specId: SpecId
  /** Ordered steps */
  steps: PlanStep[]
  /** Steps that can run in parallel (indices) */
  parallelGroups: number[][]
  /** When the plan was created */
  createdAt: number
}

/** A checkpoint (saved state for rewind/branch) */
export interface FlowCheckpoint {
  /** Unique checkpoint ID */
  id: CheckpointId
  /** Parent flow ID */
  flowId: FlowId
  /** Which step was just completed */
  stepIndex: number
  /** Description of state at checkpoint */
  description: string
  /** Git reference (commit hash or stash ref) */
  gitRef: string
  /** AI context summary at this point */
  contextSummary: string
  /** Test results at this point */
  testResults?: TestResults
  /** Spec progress: which steps are done */
  completedSteps: number[]
  /** When the checkpoint was saved */
  createdAt: number
}

/** The complete flow state, persisted to .sandcode/flow.json */
export interface FlowState {
  /** Schema version */
  version: 1
  /** Unique flow ID */
  id: FlowId
  /** Current status */
  status: FlowStatus
  /** Original user intent */
  intent: string
  /** Generated spec (if any) */
  spec?: FlowSpec
  /** Generated plan (if any) */
  plan?: FlowPlan
  /** Current step index (which step is executing) */
  currentStepIndex: number
  /** Checkpoint IDs in order */
  checkpoints: CheckpointId[]
  /** When the flow started */
  startedAt: number
  /** When the flow completed (if completed) */
  completedAt?: number
  /** Session ID that started this flow */
  sessionId: string
}

/** Re-export Forge types from the Forge service */
export type { ForgeConfig, ForgeRunResult, ForgeStatus } from '../Forge/types.js'

/** Default configuration values */
export const FLOW_DEFAULTS = {
  maxIterationsPerStep: 5,
  maxCheckpointHistory: 50,
  checkpointDir: '.sandcode/checkpoints',
  specsDir: '.sandcode/specs',
  flowFile: '.sandcode/flow.json',
  forgeFile: '.sandcode/forge.json',
} as const
