///|
pub struct ValueEstimate {
  average_order : Int
  repeat_interval : Int
  expected_orders : Int
  estimated_value : Int
}

///|
pub struct ChurnScore {
  score : Int
  reasons : Array[String]
}

///|
pub struct ScoringConfig {
  at_risk_days : Int
  dormant_days : Int
  repeat_bonus : Int
  high_value_threshold : Int
}

///|
pub fn ScoringConfig::default() -> ScoringConfig {
  {
    at_risk_days: 30,
    dormant_days: 60,
    repeat_bonus: 15,
    high_value_threshold: 500,
  }
}

///|
/// Estimate value using average order value and observed repeat interval.
pub fn estimate_lifetime_value(metrics : CustomerMetrics) -> ValueEstimate {
  let average_order = if metrics.frequency == 0 {
    0
  } else {
    metrics.monetary / metrics.frequency
  }
  let repeat_interval = if metrics.frequency <= 1 {
    0
  } else {
    (metrics.last_day - metrics.first_day) / (metrics.frequency - 1)
  }
  let expected_orders = if repeat_interval == 0 {
    1
  } else {
    365 / repeat_interval + 1
  }
  {
    average_order,
    repeat_interval,
    expected_orders,
    estimated_value: average_order * expected_orders,
  }
}

///|
/// Score churn risk from observable behavior and retain human-readable reasons.
pub fn score_churn(
  metrics : CustomerMetrics,
  config : ScoringConfig,
) -> ChurnScore {
  let mut score = 0
  let reasons : Array[String] = []
  if metrics.recency >= config.dormant_days {
    score += 70
    reasons.push("no activity for the dormant window")
  } else if metrics.recency >= config.at_risk_days {
    score += 45
    reasons.push("activity is outside the repeat-purchase window")
  }
  if metrics.frequency <= 1 {
    score += 15
    reasons.push("only one observed purchase")
  } else {
    score -= config.repeat_bonus
    reasons.push("repeat purchase history reduces risk")
  }
  if metrics.monetary >= config.high_value_threshold {
    score += 5
    reasons.push("high value deserves attention")
  }
  let bounded = if score < 0 { 0 } else if score > 100 { 100 } else { score }
  { score: bounded, reasons }
}