/* ------------------------------------------------------------------
 * College & University (Campus) grading — Bangladesh scales
 *
 * GPA5 — Higher Secondary (HSC) certificate scale of the education
 *        boards (Dhaka, Rajshahi, …): letter grades on a 5.00-point
 *        GPA with pass marks 33.
 * GPA4 — UGC / National University scale used by public & private
 *        universities and NU degree/honours programmes: 4.00-point
 *        GPA with pass marks 40.
 * ------------------------------------------------------------------ */

export type GradeStep = { min: number; grade: string; point: number };

export const CU_GRADE_SCALES: Record<string, readonly GradeStep[]> = {
  // Board HSC (college) — 5.00 scale
  GPA5: [
    { min: 80, grade: "A+", point: 5.0 },
    { min: 70, grade: "A", point: 4.0 },
    { min: 60, grade: "A-", point: 3.5 },
    { min: 50, grade: "B", point: 3.0 },
    { min: 40, grade: "C", point: 2.0 },
    { min: 33, grade: "D", point: 1.0 },
    { min: 0, grade: "F", point: 0.0 },
  ],
  // UGC / National University — 4.00 scale
  GPA4: [
    { min: 80, grade: "A+", point: 4.0 },
    { min: 75, grade: "A", point: 3.75 },
    { min: 70, grade: "A-", point: 3.5 },
    { min: 65, grade: "B+", point: 3.25 },
    { min: 60, grade: "B", point: 3.0 },
    { min: 55, grade: "B-", point: 2.75 },
    { min: 50, grade: "C+", point: 2.5 },
    { min: 45, grade: "C", point: 2.25 },
    { min: 40, grade: "D", point: 2.0 },
    { min: 0, grade: "F", point: 0.0 },
  ],
};

/** Letter grade + point for a percentage on the given scale ("GPA4"/"GPA5"). */
export function cuGradeFor(scale: string, percent: number): GradeStep {
  const steps = CU_GRADE_SCALES[scale] ?? CU_GRADE_SCALES.GPA4;
  for (const step of steps) {
    if (percent >= step.min) return step;
  }
  return steps[steps.length - 1];
}

/** Grade point averaged over credit hours: Σ(point × credit) / Σcredit.
    Failed courses keep their credits in the denominator (BD convention).
    Non-credit programs (e.g. HSC) give every course equal weight. */
export function cuGpa(items: { point: number; credits: number }[]): number {
  if (items.length === 0) return 0;
  const creditBased = items.filter((i) => i.credits > 0);
  if (creditBased.length === 0) {
    return items.reduce((s, i) => s + i.point, 0) / items.length;
  }
  const credits = creditBased.reduce((s, i) => s + i.credits, 0);
  return creditBased.reduce((s, i) => s + i.point * i.credits, 0) / credits;
}

/** Human range label for a grade-scale row ("≥80%", "70–79%", "<33%"). */
export function cuGradeRange(steps: readonly GradeStep[], idx: number): string {
  const min = steps[idx].min;
  const top = idx > 0 ? steps[idx - 1].min : null;
  if (top === null) return `≥${min}%`;
  if (min === 0) return `<${top}%`;
  return `${min}–${top - 1}%`;
}
