///|
pub(all) struct MoonfishProductStatus {
  workspace : @workspace.AnalysisWorkspace
  settings_plan : @config.SuiteSettingsPlan
  import_plan : @migration.LegacyImportPlan
  import_projection : @migration.LegacyImportProjection
  skill_migration_plan : @skills.SkillMigrationPlan
  pack_manifest : @pack.PackManifest
  parity_report : @parity.ParityReport
  comparison_report : @comparison.CutoverComparisonReport
  acceptance_report : @acceptance.AcceptanceReport
  readiness_report : @evaluation.CutoverReadinessReport
  cutover_plan : @cutover.CutoverPlan
  handoff_report : @handoff.OperatorHandoffReport
  decommission_report : @decommission.DecommissionReport
  summary : String
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct ProductStatusInput {
  workspace : @workspace.AnalysisWorkspace
  settings_plan : @config.SuiteSettingsPlan
  import_plan : @migration.LegacyImportPlan
  skill_migration_plan : @skills.SkillMigrationPlan
  comparison_bundle : @workflow.AnalysisRunBundle
  pack_manifest : @pack.PackManifest
} derive(Debug, Eq, ToJson, FromJson)

///|
pub fn product_status_input(
  workspace : @workspace.AnalysisWorkspace,
  settings_plan : @config.SuiteSettingsPlan,
  import_plan : @migration.LegacyImportPlan,
  comparison_bundle : @workflow.AnalysisRunBundle,
  skill_migration_plan? : @skills.SkillMigrationPlan = @skills.prepare_skill_migration_plan(),
  pack_manifest? : @pack.PackManifest = @pack.price_action_manifest(),
) -> ProductStatusInput {
  {
    workspace,
    settings_plan,
    import_plan,
    skill_migration_plan,
    comparison_bundle,
    pack_manifest,
  }
}

///|
fn fixture_diagnosis() -> @domain.Stage1Diagnosis {
  @domain.stage1_diagnosis(TightChannel, Bullish, 72, Stable, [AlwaysIn, H2], key_signals=[
    "three closed bull bars", "second-entry continuation",
  ])
}

///|
fn fixture_decision() -> @domain.Stage2Decision {
  @domain.stage2_decision(
    Wait,
    64,
    "dry-run fixture only; no executable order path exists",
  )
}

///|
fn fixture_suite_status() -> @model.SuiteStatusRef {
  @model.suite_status_ref(
    @model.moonsuite_suite_status_path(),
    "fixture://model/v1",
    "fixture-model",
    catalog=[
      @model.model_catalog_entry(
        "fixture-model",
        owner="moongate",
        context_window=128000,
      ),
    ],
  )
}

///|
fn demo_workspace(
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> @workspace.AnalysisWorkspace {
  @workspace.prepare_analysis_workspace(
    @workspace.analysis_workspace_input(
      "run-demo",
      "fixture smoke analysis",
      Fixture,
      "BTCUSDT",
      "15m",
      fixture_suite_status(),
      diagnosis,
      decision,
      limit=20,
      captured_at_ms=0L,
    ),
  )
}

///|
fn demo_import_plan() -> @migration.LegacyImportPlan {
  @migration.prepare_legacy_import_plan(
    @migration.legacy_import_batch_input("run-demo-import", "../paa", [
      @migration.legacy_source_ref(
        "records/pending/run-demo.json",
        LegacyPendingRecord,
        "run-demo-pending",
        target_run_id="run-demo-legacy",
      ),
    ]),
  )
}

///|
fn demo_settings_plan() -> @config.SuiteSettingsPlan {
  @config.prepare_suite_settings_plan(
    @config.legacy_settings_ref(
      "config/settings.json",
      "fixture-model",
      "fixture://model/v1",
      "fixture",
      "BTCUSDT",
      "15m",
      analysis_bar_count=20,
    ),
  )
}

///|
fn live_rehearsal_bars() -> Array[@domain.KlineBar] {
  let bars : Array[@domain.KlineBar] = []
  for index in 0..<20 {
    let base = 100.0 + index.to_double()
    bars.push(
      @domain.kline_bar(
        index,
        base,
        base + 2.0,
        base - 1.0,
        base + 1.0,
        volume=1000.0 + index.to_double(),
        closed=true,
      ),
    )
  }
  bars
}

///|
fn live_rehearsal_bundle(
  workspace : @workspace.AnalysisWorkspace,
  diagnosis : @domain.Stage1Diagnosis,
  decision : @domain.Stage2Decision,
) -> @workflow.AnalysisRunBundle {
  @workflow.run_analysis_bundle_with_snapshot(
    @workflow.analysis_run_request(
      "run-demo-live",
      "live snapshot rehearsal",
      @data.market_source_request(TradingView, "BTCUSDT", "15m", limit=20),
      workspace.plan.gateway,
      diagnosis,
      decision,
    ),
    @domain.kline_snapshot(
      "tradingview:BTCUSDT:15m:20",
      TradingView,
      "BTCUSDT",
      "15m",
      0L,
      live_rehearsal_bars(),
    ),
  )
}

///|
pub fn default_product_status_input() -> ProductStatusInput {
  let diagnosis = fixture_diagnosis()
  let decision = fixture_decision()
  let workspace = demo_workspace(diagnosis, decision)
  product_status_input(
    workspace,
    demo_settings_plan(),
    demo_import_plan(),
    live_rehearsal_bundle(workspace, diagnosis, decision),
  )
}

///|
fn product_summary(status : MoonfishProductStatus) -> String {
  "\{status.workspace.summary}; \{status.settings_plan.summary}; \{status.import_projection.summary}; \{status.skill_migration_plan.summary}; \{status.parity_report.summary}; \{status.comparison_report.summary}; \{status.acceptance_report.summary}; \{status.readiness_report.summary}; \{status.cutover_plan.summary}; \{status.handoff_report.summary}; \{status.decommission_report.summary}"
}

///|
pub fn prepare_moonfish_product_status(
  input? : ProductStatusInput = default_product_status_input(),
) -> MoonfishProductStatus {
  let import_projection = @migration.materialize_legacy_import_projection(
    input.import_plan,
  )
  let parity_report = @parity.prepare_parity_report(
    @parity.parity_report_input(input.workspace, input.import_plan),
  )
  let comparison_report = @comparison.prepare_cutover_comparison_report(
    @comparison.cutover_comparison_input(
      parity_report,
      input.workspace,
      input.comparison_bundle,
    ),
  )
  let acceptance_report = @acceptance.prepare_acceptance_report()
  let readiness_report = @evaluation.prepare_cutover_readiness_report(
    @evaluation.cutover_evaluation_input(
      input.workspace,
      input.import_plan,
      parity_report,
      comparison_report,
      skill_migration_plan=input.skill_migration_plan,
      manifest=input.pack_manifest,
    ),
  )
  let cutover_plan = @cutover.prepare_cutover_plan(
    @cutover.cutover_plan_input(readiness_report, input.import_plan),
  )
  let handoff_report = @handoff.prepare_operator_handoff_report(
    @handoff.operator_handoff_input(
      acceptance_report,
      readiness_report,
      comparison_report,
      cutover_plan,
      input.workspace.app_tool_manifest,
    ),
  )
  let decommission_report = @decommission.prepare_decommission_report(
    @decommission.decommission_input(
      cutover_plan, handoff_report, import_projection, parity_report, comparison_report,
    ),
  )
  let status : MoonfishProductStatus = {
    workspace: input.workspace,
    settings_plan: input.settings_plan,
    import_plan: input.import_plan,
    import_projection,
    skill_migration_plan: input.skill_migration_plan,
    pack_manifest: input.pack_manifest,
    parity_report,
    comparison_report,
    acceptance_report,
    readiness_report,
    cutover_plan,
    handoff_report,
    decommission_report,
    summary: "",
  }
  { ..status, summary: product_summary(status) }
}