///|
pub(all) enum OperatorPanel {
  DataSourcePanel
  ChartPanel
  DecisionPanel
  EventStreamPanel
  PromptDebugPanel
  ReviewPanel
  FollowUpPanel
  ExportPanel
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) enum OperatorAction {
  ConfigureDataSource
  SubmitMarketSnapshot
  RunAnalysis
  InspectChart
  InspectEvents
  InspectPrompts
  InspectReviews
  StartFollowUp
  ExportRun
  ReplayRun
} derive(Debug, Eq, ToJson, FromJson)

///|
pub(all) struct OperatorRunView {
  run_id : @domain.RunId
  status : @workflow.AnalysisRunStatus
  title : String
  symbol : @domain.Symbol
  timeframe : @domain.Timeframe
  adapter : String
  model : String
  chart_path : String?
  event_count : Int
  book_artifact_count : Int
  review_count : Int
  blocking_review_count : Int
  followup_topic_count : Int
  replay_available : Bool
  replay_step_count : Int
  export_item_count : Int
  panels : Array[OperatorPanel]
  actions : Array[OperatorAction]
} derive(Debug, Eq, ToJson, FromJson)

///|
fn blocking_review_count(queue : @review.ReviewQueue) -> Int {
  queue.items.fold(init=0, fn(count, item) {
    if item.priority is Blocking {
      count + 1
    } else {
      count
    }
  })
}

///|
fn event_count(bundle : @workflow.AnalysisRunBundle) -> Int {
  match bundle.projection {
    Some(projection) => projection.result.events.length()
    None => 0
  }
}

///|
fn artifact_count(bundle : @workflow.AnalysisRunBundle) -> Int {
  match bundle.write_plan {
    Some(plan) => plan.artifacts.length()
    None => 0
  }
}

///|
fn chart_path(bundle : @workflow.AnalysisRunBundle) -> String? {
  match bundle.chart_frame {
    Some(frame) => Some(frame.artifact_path)
    None => None
  }
}

///|
fn completed_panels(review_count : Int) -> Array[OperatorPanel] {
  let panels = [
    DataSourcePanel,
    ChartPanel,
    DecisionPanel,
    EventStreamPanel,
    PromptDebugPanel,
    FollowUpPanel,
    ExportPanel,
  ]
  if review_count > 0 {
    panels.push(ReviewPanel)
  }
  panels
}

///|
fn completed_actions(review_count : Int) -> Array[OperatorAction] {
  let actions = [
    ConfigureDataSource,
    RunAnalysis,
    InspectChart,
    InspectEvents,
    InspectPrompts,
    StartFollowUp,
    ExportRun,
    ReplayRun,
  ]
  if review_count > 0 {
    actions.push(InspectReviews)
  }
  actions
}

///|
fn planned_panels() -> Array[OperatorPanel] {
  [DataSourcePanel, ReviewPanel, FollowUpPanel]
}

///|
fn planned_actions() -> Array[OperatorAction] {
  [
    ConfigureDataSource,
    SubmitMarketSnapshot,
    RunAnalysis,
    InspectReviews,
    StartFollowUp,
  ]
}

///|
pub fn operator_run_view(
  bundle : @workflow.AnalysisRunBundle,
) -> OperatorRunView {
  let follow_up = @followup.prepare_follow_up_context(bundle)
  let replay_plan = @replay.prepare_replay_plan(bundle)
  let export_manifest = @export.prepare_export_manifest(bundle)
  let review_count = follow_up.review_queue.items.length()
  let status = bundle.status
  {
    run_id: bundle.request.run_id,
    status,
    title: bundle.request.operator_request,
    symbol: bundle.request.market.symbol,
    timeframe: bundle.request.market.timeframe,
    adapter: bundle.market_fetch.plan.adapter,
    model: bundle.request.gateway.default_model,
    chart_path: chart_path(bundle),
    event_count: event_count(bundle),
    book_artifact_count: artifact_count(bundle),
    review_count,
    blocking_review_count: blocking_review_count(follow_up.review_queue),
    followup_topic_count: follow_up.suggested_topics.length(),
    replay_available: replay_plan.can_replay,
    replay_step_count: replay_plan.steps.length(),
    export_item_count: export_manifest.item_count,
    panels: if status is Completed {
      completed_panels(review_count)
    } else {
      planned_panels()
    },
    actions: if status is Completed {
      completed_actions(review_count)
    } else {
      planned_actions()
    },
  }
}