"use client";

import { formatDate } from "@/lib/utils";
import { mix, reportFooterHtml } from "@/lib/report-html";
import { CU_GRADE_SCALES, cuGradeRange, type GradeStep } from "@/lib/campus-grades";

/* Printable College & University (campus) reports: exam routine, semester
   marksheet, tabulation sheet and academic transcript. All styling is
   inline — same conventions as the school-level report builders. */

export interface CampusInst {
  name: string;
  logo?: string | null;
  address?: string | null;
}

const dash = "—";

function page(title: string, bodyHtml: string, primary: string, landscape = false): string {
  return `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>${title}</title>
<style>
  @page { size: A4 ${landscape ? "landscape" : "portrait"}; margin: 12mm; }
  * { box-sizing: border-box; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  body { font-family: "Montserrat", "Noto Sans Bengali", Arial, sans-serif; color: #21262f; margin: 0; padding: 18px; }
  table { width: 100%; border-collapse: collapse; }
  th, td { border: 1px solid #d7dee8; padding: 6px 8px; font-size: 12px; vertical-align: middle; }
  th { background: ${mix(primary, "#ffffff", 0.85)}; text-align: left; }
  .rpt-head { display: flex; align-items: center; gap: 12px; border-bottom: 3px solid ${primary}; padding-bottom: 10px; margin-bottom: 12px; }
  .rpt-head img { width: 56px; height: 56px; object-fit: contain; }
  .rpt-head .initials { width: 56px; height: 56px; border-radius: 50%; background: ${primary}; color: #fff; font-weight: 800; font-size: 20px; display: flex; align-items: center; justify-content: center; }
  .rpt-title h1 { font-size: 19px; margin: 0; color: ${primary}; }
  .rpt-title p { margin: 2px 0 0; font-size: 12px; color: #67718a; }
  .band { background: ${primary}; color: #fff; text-align: center; font-weight: 700; padding: 7px 10px; font-size: 14px; border-radius: 4px; margin: 10px 0; letter-spacing: 1px; }
  .info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 18px; margin-bottom: 10px; }
  .info-grid div { font-size: 12.5px; }
  .info-grid b { color: #3c4658; }
  .totals td { font-weight: 700; background: ${mix(primary, "#ffffff", 0.92)}; }
  .center { text-align: center; }
  .sign-row { display: flex; justify-content: space-between; margin-top: 34px; padding: 0 10px; }
  .sign-row div { font-size: 12px; color: #3c4658; text-align: center; }
  .sign-row span { display: block; border-top: 1px solid #3c4658; margin-top: 34px; padding-top: 4px; min-width: 180px; }
  .muted { color: #8a94a6; }
  .pass { color: #1c7a43; font-weight: 700; }
  .fail { color: #b02a37; font-weight: 700; }
</style>
</head>
<body>
${bodyHtml}
</body>
</html>`;
}

function header(inst: CampusInst | null, subtitle: string): string {
  const name = inst?.name ?? "IncrelogEMS";
  const initials = name.split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
  return `<div class="rpt-head">
    ${inst?.logo ? `<img src="${inst.logo}" alt="" />` : `<div class="initials">${initials}</div>`}
    <div class="rpt-title">
      <h1>${name}</h1>
      <p>${subtitle}</p>
    </div>
  </div>`;
}

function footer(primary: string, accent: string, poweredBy: string, scanLabel: string): string {
  return reportFooterHtml({ primary, accent, scanLabel, poweredBy, reportLabel: "" });
}

/* ------------------------- exam routine ------------------------- */

export interface CampusRoutinePaper {
  courseCode: string;
  courseName: string;
  courseNameBn: string | null;
  credits: number;
  courseType?: string | null;
  examDate: string | null;
  startTime: string | null;
  endTime: string | null;
  room: string | null;
  fullMarks: number;
  passMarks: number;
}

export interface CampusRoutineLabels {
  routineTitle: string;
  program: string;
  term: string;
  session: string;
  examDates: string;
  papers: string;
  course: string;
  credits: string;
  date: string;
  time: string;
  room: string;
  marks: string;
  passMarks: string;
}

export function buildCampusRoutineHtml(opts: {
  inst: CampusInst | null;
  locale: string;
  examName: string;
  programName: string;
  termName: string | null;
  sessionYear: string | null;
  startDate: string | null;
  endDate: string | null;
  papers: CampusRoutinePaper[];
  labels: CampusRoutineLabels;
  primary: string;
  accent: string;
  poweredBy: string;
  scanLabel: string;
}): string {
  const L = opts.labels;
  const name = (en: string, bn: string | null) => (opts.locale === "bn" && bn ? bn : en);
  const rows = opts.papers
    .map(
      (p, i) => `<tr>
        <td class="center muted">${i + 1}</td>
        <td><b>${p.courseCode}</b> — ${name(p.courseName, p.courseNameBn)}</td>
        <td class="center">${p.credits}</td>
        <td>${p.examDate ? formatDate(p.examDate, opts.locale as "en" | "bn") : dash}</td>
        <td class="center">${p.startTime && p.endTime ? `${p.startTime} → ${p.endTime}` : dash}</td>
        <td class="center">${p.room ?? dash}</td>
        <td class="center"><b>${p.fullMarks}</b> / ${p.passMarks}</td>
      </tr>`
    )
    .join("");
  const body = `
${header(opts.inst, L.routineTitle)}
<div class="band">${opts.examName}</div>
<div class="info-grid">
  <div><b>${L.program}:</b> ${opts.programName}</div>
  <div><b>${L.term}:</b> ${opts.termName ?? dash}</div>
  <div><b>${L.session}:</b> ${opts.sessionYear ?? dash}</div>
  <div><b>${L.examDates}:</b> ${opts.startDate ? formatDate(opts.startDate, opts.locale as "en" | "bn") : dash}${opts.endDate ? ` → ${formatDate(opts.endDate, opts.locale as "en" | "bn")}` : ""}</div>
  <div><b>${L.papers}:</b> ${opts.papers.length}</div>
</div>
<table>
  <thead><tr><th>#</th><th>${L.course}</th><th class="center">${L.credits}</th><th>${L.date}</th><th class="center">${L.time}</th><th class="center">${L.room}</th><th class="center">${L.marks} / ${L.passMarks}</th></tr></thead>
  <tbody>${rows}</tbody>
</table>
${footer(opts.primary, opts.accent, opts.poweredBy, opts.scanLabel)}`;
  return page(opts.examName, body, opts.primary, true);
}

/* ----------------------- semester marksheet ---------------------- */

export interface CampusMarksheetCourse {
  courseCode: string;
  courseName: string;
  courseNameBn: string | null;
  credits: number;
  fullMarks: number;
  passMarks: number;
  marks: number | null;
  absent: boolean;
  entered: boolean;
  percent: number | null;
  grade: string | null;
  point: number | null;
  failed: boolean;
}

export interface CampusMarksheetLabels {
  marksheetTitle: string;
  studentId: string;
  name: string;
  program: string;
  term: string;
  session: string;
  exam: string;
  course: string;
  credits: string;
  fullMarks: string;
  passMarks: string;
  obtained: string;
  percent: string;
  grade: string;
  point: string;
  totals: string;
  gpa: string;
  result: string;
  scale: string;
  preparedBy: string;
  examController: string;
  passed: string;
  failed: string;
  incomplete: string;
  absentShort: string;
  notEntered: string;
}

export function buildCampusMarksheetHtml(opts: {
  inst: CampusInst | null;
  locale: string;
  student: { studentIdNo: string; name: string; nameBn: string | null; sessionYear: string; boardRollNo?: string | null; registrationNo?: string | null };
  examName: string;
  programName: string;
  programScale: string;
  termName: string | null;
  sessionYear: string | null;
  courses: CampusMarksheetCourse[];
  creditsAttempted: number;
  totalMarks: number;
  fullMarksTotal: number;
  gpa: number | null;
  status: string;
  labels: CampusMarksheetLabels;
  primary: string;
  accent: string;
  poweredBy: string;
  scanLabel: string;
}): string {
  const L = opts.labels;
  const stName = opts.locale === "bn" && opts.student.nameBn ? opts.student.nameBn : opts.student.name;
  const statusText = opts.status === "PASSED" ? L.passed : opts.status === "FAILED" ? L.failed : L.incomplete;
  const statusCls = opts.status === "PASSED" ? "pass" : opts.status === "FAILED" ? "fail" : "muted";
  const scaleSteps = CU_GRADE_SCALES[opts.programScale] ?? CU_GRADE_SCALES.GPA4;
  const scaleText = scaleSteps
    .map((s: GradeStep, i: number) => `${s.grade} (${cuGradeRange(scaleSteps, i)}) = ${s.point.toFixed(2)}`)
    .join(" · ");

  const rows = opts.courses
    .map((c) => {
      const obtained = !c.entered ? `<span class="muted">${L.notEntered}</span>` : c.absent ? `<span class="fail">${L.absentShort}</span>` : c.marks!;
      return `<tr>
        <td><b>${c.courseCode}</b> — ${opts.locale === "bn" && c.courseNameBn ? c.courseNameBn : c.courseName}</td>
        <td class="center">${c.credits}</td>
        <td class="center">${c.fullMarks}</td>
        <td class="center">${c.passMarks}</td>
        <td class="center"><b>${obtained}</b></td>
        <td class="center">${c.percent ?? dash}</td>
        <td class="center">${c.grade ?? dash}</td>
        <td class="center">${c.point ?? dash}</td>
      </tr>`;
    })
    .join("");

  const body = `
${header(opts.inst, L.marksheetTitle)}
<div class="band">${opts.examName}</div>
<div class="info-grid">
  <div><b>${L.name}:</b> ${stName}</div>
  <div><b>${L.studentId}:</b> ${opts.student.studentIdNo}</div>
  <div><b>${L.program}:</b> ${opts.programName}</div>
  <div><b>${L.term}:</b> ${opts.termName ?? dash}</div>
  <div><b>${L.session}:</b> ${opts.sessionYear ?? dash}</div>
  <div><b>${L.result}:</b> <span class="${statusCls}">${statusText}</span></div>
</div>
<table>
  <thead><tr><th>${L.course}</th><th class="center">${L.credits}</th><th class="center">${L.fullMarks}</th><th class="center">${L.passMarks}</th><th class="center">${L.obtained}</th><th class="center">${L.percent}</th><th class="center">${L.grade}</th><th class="center">${L.point}</th></tr></thead>
  <tbody>
    ${rows}
    <tr class="totals">
      <td class="center">${L.totals}</td>
      <td class="center">${opts.creditsAttempted}</td>
      <td class="center">${opts.fullMarksTotal}</td>
      <td></td>
      <td class="center">${opts.totalMarks}</td>
      <td colspan="2" class="center">${L.gpa}: ${opts.gpa ?? dash}</td>
      <td class="center">${statusText}</td>
    </tr>
  </tbody>
</table>
<p style="font-size:11px;color:#67718a;margin-top:8px"><b>${L.scale}:</b> ${scaleText}</p>
<div class="sign-row">
  <div><span>${L.preparedBy}</span></div>
  <div><span>${L.examController}</span></div>
</div>
${footer(opts.primary, opts.accent, opts.poweredBy, opts.scanLabel)}`;
  return page(`${opts.examName} — ${stName}`, body, opts.primary);
}

/* ----------------------- tabulation sheet ------------------------ */

export interface CampusTabulationRow {
  studentIdNo: string;
  name: string;
  nameBn: string | null;
  cells: (string | null)[]; // grade (or mark) per course column, aligned with headers
  gpa: number | null;
  status: string;
}

export function buildCampusTabulationHtml(opts: {
  inst: CampusInst | null;
  locale: string;
  examName: string;
  programName: string;
  termName: string | null;
  sessionYear: string | null;
  courseCodes: string[];
  rows: CampusTabulationRow[];
  labels: { tabulationTitle: string; student: string; gpa: string; result: string; passed: string; failed: string; incomplete: string };
  primary: string;
  accent: string;
  poweredBy: string;
  scanLabel: string;
}): string {
  const L = opts.labels;
  const st = (s: string) => (s === "PASSED" ? L.passed : s === "FAILED" ? L.failed : L.incomplete);
  const bodyRows = opts.rows
    .map(
      (r, i) => `<tr>
      <td class="center muted">${i + 1}</td>
      <td><b>${r.studentIdNo}</b></td>
      <td>${opts.locale === "bn" && r.nameBn ? r.nameBn : r.name}</td>
      ${r.cells.map((c) => `<td class="center">${c ?? dash}</td>`).join("")}
      <td class="center"><b>${r.gpa ?? dash}</b></td>
      <td class="center">${st(r.status)}</td>
    </tr>`
    )
    .join("");
  const body = `
${header(opts.inst, L.tabulationTitle)}
<div class="band">${opts.examName}</div>
<div class="info-grid">
  <div><b>${opts.courseCodes.length} ${opts.examName ? "" : ""}</div>
</div>
<table>
  <thead><tr><th>#</th><th>${L.student}</th><th></th>${opts.courseCodes.map((c) => `<th class="center">${c}</th>`).join("")}<th class="center">${L.gpa}</th><th class="center">${L.result}</th></tr></thead>
  <tbody>${bodyRows}</tbody>
</table>
${footer(opts.primary, opts.accent, opts.poweredBy, opts.scanLabel)}`;
  return page(opts.examName, body, opts.primary, true);
}

/* ---------------------- academic transcript ---------------------- */

export interface CampusTranscriptTerm {
  examName: string;
  termName: string;
  termNameBn: string | null;
  courses: { code: string; name: string; nameBn: string | null; credits: number; marks: number | null; fullMarks: number; grade: string; point: number }[];
  credits: number;
  gpa: number;
}

export function buildCampusTranscriptHtml(opts: {
  inst: CampusInst | null;
  locale: string;
  student: { studentIdNo: string; name: string; nameBn: string | null; sessionYear: string; boardRollNo?: string | null; registrationNo?: string | null };
  programName: string;
  faculty: string | null;
  department: string | null;
  programScale: string;
  terms: CampusTranscriptTerm[];
  cgpa: number | null;
  totalCredits: number;
  programCredits: number;
  labels: {
    transcriptTitle: string;
    name: string;
    studentId: string;
    program: string;
    faculty: string;
    department: string;
    session: string;
    boardRoll: string;
    registration: string;
    course: string;
    credits: string;
    obtained: string;
    grade: string;
    point: string;
    gpa: string;
    creditsCompleted: string;
    cgpa: string;
    scale: string;
    examController: string;
    registrar: string;
  };
  primary: string;
  accent: string;
  poweredBy: string;
  scanLabel: string;
}): string {
  const L = opts.labels;
  const stName = opts.locale === "bn" && opts.student.nameBn ? opts.student.nameBn : opts.student.name;
  const scaleSteps = CU_GRADE_SCALES[opts.programScale] ?? CU_GRADE_SCALES.GPA4;
  const scaleText = scaleSteps
    .map((s: GradeStep, i: number) => `${s.grade} (${cuGradeRange(scaleSteps, i)}) = ${s.point.toFixed(2)}`)
    .join(" · ");

  const termBlocks = opts.terms
    .map(
      (t) => `<div style="margin-bottom:14px">
      <div style="font-weight:800;font-size:13px;color:${opts.primary};margin-bottom:4px">
        ${opts.locale === "bn" && t.termNameBn ? t.termNameBn : t.termName} — ${t.examName}
      </div>
      <table>
        <thead><tr><th>${L.course}</th><th class="center">${L.credits}</th><th class="center">${L.obtained}</th><th class="center">${L.grade}</th><th class="center">${L.point}</th></tr></thead>
        <tbody>
          ${t.courses
            .map(
              (c) => `<tr>
              <td><b>${c.code}</b> — ${opts.locale === "bn" && c.nameBn ? c.nameBn : c.name}</td>
              <td class="center">${c.credits}</td>
              <td class="center">${c.marks ?? dash} / ${c.fullMarks}</td>
              <td class="center"><b>${c.grade}</b></td>
              <td class="center">${c.point.toFixed(2)}</td>
            </tr>`
            )
            .join("")}
          <tr class="totals"><td class="center">${L.gpa}</td><td class="center">${t.credits}</td><td colspan="3" class="center">${t.gpa.toFixed(2)}</td></tr>
        </tbody>
      </table>
    </div>`
    )
    .join("");

  const body = `
${header(opts.inst, L.transcriptTitle)}
<div class="info-grid">
  <div><b>${L.name}:</b> ${stName}</div>
  <div><b>${L.studentId}:</b> ${opts.student.studentIdNo}</div>
  <div><b>${L.program}:</b> ${opts.programName}</div>
  <div><b>${L.faculty}:</b> ${opts.faculty ?? dash}</div>
  <div><b>${L.department}:</b> ${opts.department ?? dash}</div>
  <div><b>${L.session}:</b> ${opts.student.sessionYear}</div>
  ${opts.student.boardRollNo ? `<div><b>${L.boardRoll}:</b> ${opts.student.boardRollNo}</div>` : ""}
  ${opts.student.registrationNo ? `<div><b>${L.registration}:</b> ${opts.student.registrationNo}</div>` : ""}
</div>
<div class="band">${L.cgpa}: ${opts.cgpa?.toFixed(2) ?? dash} &nbsp;·&nbsp; ${L.creditsCompleted}: ${opts.totalCredits}${opts.programCredits > 0 ? ` / ${opts.programCredits}` : ""}</div>
${termBlocks || `<p class="muted">${dash}</p>`}
<p style="font-size:11px;color:#67718a;margin-top:8px"><b>${L.scale}:</b> ${scaleText}</p>
<div class="sign-row">
  <div><span>${L.examController}</span></div>
  <div><span>${L.registrar}</span></div>
</div>
${footer(opts.primary, opts.accent, opts.poweredBy, opts.scanLabel)}`;
  return page(`${L.transcriptTitle} — ${stName}`, body, opts.primary);
}
