// Pure delta-computation for the Vorher/Nachher-Vergleich (before/after comparison).
//
// Computes per-station: observed_ct_sec vs possible_ct_sec, absolute delta (s)
// and percentage delta. Positive savings (possible < observed) are flagged.
//
// All arithmetic is pure — no DOM, no framework. Unit-tested in __tests__/before-after.test.ts.

export interface BeforeAfterInput {
  stepId: string
  stationName: string
  stepNumber: number
  observed_ct_sec: number | null
  possible_ct_sec: number | null
}

export interface BeforeAfterRow {
  stepId: string
  stationName: string
  stepNumber: number
  observed_ct_sec: number | null
  possible_ct_sec: number | null
  /** Absolute delta: possible_ct_sec - observed_ct_sec. Negative = saving. */
  delta_sec: number | null
  /** Percentage delta relative to observed_ct_sec. Negative = saving. */
  delta_pct: number | null
  /** True when possible_ct_sec < observed_ct_sec (time is saved). */
  hasSaving: boolean
}

export interface BeforeAfterTotals {
  /** Sum of observed_ct_sec for rows where both values are present. */
  totalObserved: number | null
  /** Sum of possible_ct_sec for rows where both values are present. */
  totalPossible: number | null
  /** totalPossible - totalObserved. */
  totalDelta: number | null
  /** totalDelta / totalObserved * 100, or null if totalObserved is zero/null. */
  totalDeltaPct: number | null
}

/** Compute per-row before/after data from the raw inputs. */
export function computeBeforeAfterRows(inputs: BeforeAfterInput[]): BeforeAfterRow[] {
  return inputs.map((input) => {
    const { stepId, stationName, stepNumber, observed_ct_sec, possible_ct_sec } = input

    if (observed_ct_sec == null || possible_ct_sec == null) {
      return {
        stepId,
        stationName,
        stepNumber,
        observed_ct_sec,
        possible_ct_sec,
        delta_sec: null,
        delta_pct: null,
        hasSaving: false,
      }
    }

    const delta_sec = possible_ct_sec - observed_ct_sec
    const delta_pct =
      observed_ct_sec !== 0
        ? Math.round((delta_sec / observed_ct_sec) * 10000) / 100
        : null

    return {
      stepId,
      stationName,
      stepNumber,
      observed_ct_sec,
      possible_ct_sec,
      delta_sec,
      delta_pct,
      hasSaving: delta_sec < 0,
    }
  })
}

/**
 * Aggregate before/after rows into overall totals.
 * Only rows where both observed and possible values are present contribute.
 */
export function computeTotals(rows: BeforeAfterRow[]): BeforeAfterTotals {
  const completeRows = rows.filter(
    (r) => r.observed_ct_sec != null && r.possible_ct_sec != null,
  )

  if (completeRows.length === 0) {
    return {
      totalObserved: null,
      totalPossible: null,
      totalDelta: null,
      totalDeltaPct: null,
    }
  }

  const totalObserved = completeRows.reduce(
    (sum, r) => sum + (r.observed_ct_sec ?? 0),
    0,
  )
  const totalPossible = completeRows.reduce(
    (sum, r) => sum + (r.possible_ct_sec ?? 0),
    0,
  )
  const totalDelta = totalPossible - totalObserved
  const totalDeltaPct =
    totalObserved !== 0
      ? Math.round((totalDelta / totalObserved) * 10000) / 100
      : null

  return { totalObserved, totalPossible, totalDelta, totalDeltaPct }
}
