///|
/// One stable quality dashboard card.
pub(all) struct DashboardCard {
  key : String
  label : String
  value : String
  status : String
}

///|
/// Dashboard assembled from the same plan and observations as reports.
pub(all) struct QualityDashboard {
  part_id : String
  summary : ProgramSummary
  cards : Array[DashboardCard]
  status : String
}

///|
fn dashboard_card(
  key : String,
  label : String,
  value : String,
  status : String,
) -> DashboardCard {
  { key, label, value, status }
}

///|
/// Build four stable cards for a plan run.
pub fn build_dashboard(
  features~ : Array[Feature],
  observations~ : Array[Observation],
  plan~ : MeasurementPlan,
) -> QualityDashboard {
  let summary = summarize_program(features~, observations~, plan~)
  let status = if program_is_acceptable(summary) {
    "healthy"
  } else {
    program_status(summary)
  }
  let cards = [
    dashboard_card(
      "coverage",
      "Coverage",
      summary.coverage.to_string(),
      if summary.coverage >= 1.0 {
        "ok"
      } else {
        "warn"
      },
    ),
    dashboard_card(
      "pass-rate",
      "Pass rate",
      summary.pass_rate.to_string(),
      if summary.fail_count == 0 {
        "ok"
      } else {
        "fail"
      },
    ),
    dashboard_card(
      "defect-rate",
      "Defect rate",
      summary.defect_rate.to_string(),
      if summary.defect_rate == 0.0 {
        "ok"
      } else {
        "fail"
      },
    ),
    dashboard_card(
      "cpk",
      "Minimum Cpk",
      summary.minimum_cpk.to_string(),
      if summary.minimum_cpk >= 1.33 {
        "ok"
      } else {
        "warn"
      },
    ),
  ]
  { part_id: plan.part_id, summary, cards, status }
}

///|
/// Return a card value or an empty string if the key is unknown.
pub fn dashboard_card_value(
  dashboard : QualityDashboard,
  key : String,
) -> String {
  let mut result = ""
  for card in dashboard.cards {
    if card.key == key {
      result = card.value
    }
  }
  result
}

///|
/// Return a card status or an empty string if the key is unknown.
pub fn dashboard_card_status(
  dashboard : QualityDashboard,
  key : String,
) -> String {
  let mut result = ""
  for card in dashboard.cards {
    if card.key == key {
      result = card.status
    }
  }
  result
}

///|
/// Return whether all dashboard health conditions pass.
pub fn dashboard_is_healthy(dashboard : QualityDashboard) -> Bool {
  dashboard.status == "acceptable" || dashboard.status == "healthy"
}

///|
/// Return a compact dashboard status where acceptance is healthy.
pub fn dashboard_status(dashboard : QualityDashboard) -> String {
  if dashboard_is_healthy(dashboard) {
    "healthy"
  } else {
    dashboard.status
  }
}

///|
/// Return a stable multi-line card rendering.
pub fn render_dashboard(dashboard : QualityDashboard) -> String {
  let mut output = "part=" +
    dashboard.part_id +
    "\nstatus=" +
    dashboard_status(dashboard) +
    "\n"
  for card in dashboard.cards {
    output = output +
      card.key +
      "=" +
      card.value +
      " status=" +
      card.status +
      "\n"
  }
  output
}

///|
/// Return the number of cards with a failing status.
pub fn dashboard_failure_count(dashboard : QualityDashboard) -> Int {
  let mut result = 0
  for card in dashboard.cards {
    if card.status == "fail" {
      result += 1
    }
  }
  result
}

///|
/// Return the number of cards requiring review.
pub fn dashboard_warning_count(dashboard : QualityDashboard) -> Int {
  let mut result = 0
  for card in dashboard.cards {
    if card.status == "warn" {
      result += 1
    }
  }
  result
}

///|
/// Return whether the dashboard has complete observations.
pub fn dashboard_is_complete(dashboard : QualityDashboard) -> Bool {
  dashboard.summary.unmeasured_count == 0 && dashboard.summary.coverage >= 1.0
}

///|
/// Return whether the dashboard has a clean batch outcome.
pub fn dashboard_is_clean(dashboard : QualityDashboard) -> Bool {
  dashboard.summary.fail_count == 0 && dashboard.summary.defect_rate == 0.0
}