///|
pub(all) enum CutoverStepKind {
  VerifyReadiness
  ImportLegacyData
  FreezeLegacyApp
  SwitchOperatorSurface
  MonitorRollbackWindow
  ArchiveLegacyNotes
  BlockedByReadiness
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) enum CutoverStepStatus {
  Planned
  Blocked
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct CutoverStep {
  index : Int
  kind : CutoverStepKind
  status : CutoverStepStatus
  path : String
  message : String
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct CutoverPlanInput {
  readiness : @evaluation.CutoverReadinessReport
  import_plan : @migration.LegacyImportPlan
  rollback_days : Int
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct CutoverPlan {
  ready_to_cutover : Bool
  rollback_days : Int
  imported_data_manifest_path : String
  checklist : Array[CutoverStep]
  rollback_plan : Array[CutoverStep]
  decommission_note : String
  summary : String
} derive(Debug, Eq, ToJson, FromJson)

///|
pub fn cutover_plan_input(
  readiness : @evaluation.CutoverReadinessReport,
  import_plan : @migration.LegacyImportPlan,
  rollback_days? : Int = 14,
) -> CutoverPlanInput {
  { readiness, import_plan, rollback_days }
}

///|
fn normalized_rollback_days(days : Int) -> Int {
  if days < 1 {
    1
  } else {
    days
  }
}

///|
fn step(
  index : Int,
  kind : CutoverStepKind,
  status : CutoverStepStatus,
  path : String,
  message : String,
) -> CutoverStep {
  { index, kind, status, path, message }
}

///|
fn readiness_blockers(
  readiness : @evaluation.CutoverReadinessReport,
) -> Array[CutoverStep] {
  let steps : Array[CutoverStep] = []
  let mut index = 0
  for finding in readiness.findings {
    if finding.status is NeedsWork {
      steps.push(
        step(index, BlockedByReadiness, Blocked, finding.path, finding.message),
      )
      index += 1
    }
  }
  steps
}

///|
fn ready_checklist(
  import_plan : @migration.LegacyImportPlan,
  rollback_days : Int,
) -> Array[CutoverStep] {
  [
    step(
      0,
      VerifyReadiness,
      Planned,
      "records/evaluations/cutover-readiness.json",
      "store final readiness report and operator approval",
    ),
    step(
      1,
      ImportLegacyData,
      Planned,
      "records/imports/\{import_plan.batch_id}.json",
      "write \{import_plan.ready_count} imported legacy artifact(s) into MoonBook targets",
    ),
    step(
      2,
      FreezeLegacyApp,
      Planned,
      "../paa",
      "freeze PA Agent feature development except critical fixes",
    ),
    step(
      3,
      SwitchOperatorSurface,
      Planned,
      "apps/moondesk-price-action",
      "switch daily workflow to the MoonSuite price-action app-tool",
    ),
    step(
      4,
      MonitorRollbackWindow,
      Planned,
      "records/evaluations/rollback-window.json",
      "keep PA Agent read-only for \{rollback_days} day(s)",
    ),
    step(
      5,
      ArchiveLegacyNotes,
      Planned,
      "docs/pa-agent-migration-plan.md",
      "archive migration notes, known differences, and decommission status",
    ),
  ]
}

///|
fn rollback_plan(rollback_days : Int) -> Array[CutoverStep] {
  [
    step(
      0,
      MonitorRollbackWindow,
      Planned,
      "../paa",
      "during the \{rollback_days}-day window, keep PA Agent read-only but runnable for audit comparison",
    ),
    step(
      1,
      SwitchOperatorSurface,
      Planned,
      "apps/moondesk-price-action",
      "if a blocking issue appears, switch operators back to the read-only PA Agent workflow and retain MoonBook evidence",
    ),
    step(
      2,
      ArchiveLegacyNotes,
      Planned,
      "records/evaluations/rollback-report.json",
      "record rollback reason, affected runs, and required Moonfish fixes",
    ),
  ]
}

///|
pub fn prepare_cutover_plan(input : CutoverPlanInput) -> CutoverPlan {
  let rollback_days = normalized_rollback_days(input.rollback_days)
  let ready_to_cutover = input.readiness.ready
  let imported_data_manifest_path = "records/imports/\{input.import_plan.batch_id}.json"
  let checklist = if ready_to_cutover {
    ready_checklist(input.import_plan, rollback_days)
  } else {
    readiness_blockers(input.readiness)
  }
  let decommission_note = if ready_to_cutover {
    "Moonfish is ready to become the primary workflow after import execution and the \{rollback_days}-day read-only PA Agent rollback window."
  } else {
    "Moonfish is not ready for cutover; resolve readiness blockers before freezing PA Agent."
  }
  {
    ready_to_cutover,
    rollback_days,
    imported_data_manifest_path,
    checklist,
    rollback_plan: rollback_plan(rollback_days),
    decommission_note,
    summary: if ready_to_cutover {
      "cutover plan ready with \{checklist.length()} step(s) and \{input.import_plan.ready_count} import item(s)"
    } else {
      "cutover blocked by \{checklist.length()} readiness issue(s)"
    },
  }
}