"use client";

import { useEffect, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import { Button, Card, EmptyState, Modal, PageHeader, LoadingArea } from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatDate } from "@/lib/utils";
import { IconCalendar, IconClipboard, IconFile } from "@/components/icons";
import { DEFAULT_ACCENT, DEFAULT_PRIMARY, openPrintWindow } from "@/lib/print";
import { admitCardHtml, type AdmitCardPaper, type AdmitVariant } from "@/lib/admit-card";
import QRCodeStyling from "qr-code-styling";
import {
  buildExamScheduleReportHtml,
  type ScheduleReportLabels,
  type ScheduleReportExam,
  type ScheduleReportPaper,
} from "@/lib/exam-schedule-report";

interface ScheduleRow {
  id: number;
  date: string;
  startTime: string | null;
  endTime: string | null;
  fullMarks: number;
  totalPassMarks: number | null;
  subjectItem: { name: string; nameBn: string | null } | null;
  roomItem: { name: string; nameBn: string | null } | null;
}

interface ExamRoutine {
  id: number;
  name: string;
  nameBn: string | null;
  className: string | null;
  classNameBn: string | null;
  status: string;
  startDate: string;
  endDate: string | null;
  note: string | null;
  resultPublished: boolean;
  schedules: ScheduleRow[];
}

interface AdmitCardData {
  exam: {
    id: number;
    name: string;
    nameBn: string | null;
    className: string | null;
    classNameBn: string | null;
    sectionName: string | null;
    startDate: string;
    endDate: string | null;
  };
  student: {
    id: number;
    roll: string;
    name: string;
    nameBn: string | null;
    photoUrl?: string | null;
    verifyCode?: string | null;
  };
  papers: AdmitCardPaper[];
  institution: { name: string; address: string; phone: string; logo: string | null } | null;
}

/** Student/parent: published exam routines (date, time, room, marks) with a
    printable admit card and the same routine report design the institution
    portal prints. Operational exam statuses (Upcoming/Running/…) are never
    shown here — only what the institution published. */
export default function MeExamsPage() {
  const { t, locale } = useLang();
  const { data, loading } = useApi<{ exams: ExamRoutine[] }>("/api/me/exams");
  const L = t.portal.certificatesPage;

  // admit card modal: fetched per exam, previewed and printed like the portal
  const [admit, setAdmit] = useState<AdmitCardData | null>(null);
  const [admitOpen, setAdmitOpen] = useState(false);
  const [admitLoading, setAdmitLoading] = useState(false);
  const [admitVariant, setAdmitVariant] = useState<AdmitVariant>("detailed");
  // verification QR rendered from the minted admit-card code
  const [admitQr, setAdmitQr] = useState<string | null>(null);

  useEffect(() => {
    if (!admit || !admit.student.verifyCode) {
      setAdmitQr(null);
      return;
    }
    let cancelled = false;
    (async () => {
      try {
        const qr = new QRCodeStyling({
          width: 240,
          height: 240,
          margin: 8,
          data: admit.student.verifyCode!,
          backgroundOptions: { color: "#ffffff" },
          dotsOptions: { type: "rounded", color: "#14514a" },
          cornersSquareOptions: { type: "extra-rounded", color: "#14514a" },
        });
        const blob = (await qr.getRawData("png")) as Blob | null;
        if (!cancelled && blob) setAdmitQr(URL.createObjectURL(blob));
      } catch {
        if (!cancelled) setAdmitQr(null);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [admit]);
  // per-exam print-in-flight state
  const [printingId, setPrintingId] = useState<number | null>(null);

  async function openAdmitCard(examId: number) {
    setAdmitLoading(true);
    setAdmitOpen(true);
    try {
      const res = await api<AdmitCardData>(`/api/me/admit-card?examId=${examId}`);
      setAdmit(res);
    } catch {
      setAdmit(null);
    } finally {
      setAdmitLoading(false);
    }
  }

  const admitHtml = admit
    ? admitCardHtml({
        inst: admit.institution,
        exam: admit.exam,
        papers: admit.papers,
        student: admit.student,
        qrDataUrl: admitQr,
        variant: admitVariant,
        labels: { ...L, verifyScan: L.verifyScan },
        locale,
        poweredBy: t.landing.poweredBy,
      })
    : "";

  function printAdmitCard() {
    if (!admit) return;
    openPrintWindow(L.admitCard, locale, admitHtml);
  }

  /** printable routine — same builder/design as the portal schedule report */
  async function printRoutine(e: ExamRoutine) {
    setPrintingId(e.id);
    try {
      const res = await api<AdmitCardData>(`/api/me/admit-card?examId=${e.id}`);
      const EL = t.portal.examsPage;
      const labels: ScheduleReportLabels = {
        summaryReport: EL.summaryReport,
        detailsReport: EL.detailsReport,
        branchLabel: EL.branchLabel,
        mainBranch: EL.mainBranch,
        classLabel: EL.classLabel,
        sectionLabel: EL.sectionLabel,
        groupLabel: EL.groupLabel,
        departmentLabel: EL.departmentLabel,
        shiftLabel: EL.shiftLabel,
        startDate: EL.startDate,
        endDate: EL.endDate,
        totalPapers: EL.totalPapers,
        subject: EL.subject,
        date: EL.date,
        startTime: EL.startTime,
        endTime: EL.endTime,
        room: EL.room,
        appliedExamDate: EL.appliedExamDate,
        marksColumn: EL.marksColumn,
        fullPass: EL.fullPass,
        appliedShort: EL.appliedShort,
        reportTitle: EL.reportTitle,
        publishedBadge: EL.publishedBadge,
        generatedOn: EL.generatedOn,
        preparedBy: EL.preparedBy,
        approvedBy: EL.approvedBy,
        scanToVerify: t.portal.resultsPage.scanToVerify,
      };
      const html = await buildExamScheduleReportHtml({
        kind: "details",
        exam: {
          id: res.exam.id,
          name: res.exam.name,
          nameBn: res.exam.nameBn,
          className: res.exam.className,
          sectionName: res.exam.sectionName,
          startDate: res.exam.startDate,
          endDate: res.exam.endDate,
        } as ScheduleReportExam,
        schedules: res.papers as ScheduleReportPaper[],
        inst: res.institution,
        locale,
        labels,
        noteLabel: t.common.note,
        statusText: null, // operational statuses stay in the office
        primary: DEFAULT_PRIMARY,
        accent: DEFAULT_ACCENT,
        showQr: false,
        poweredBy: t.landing.poweredBy,
      });
      openPrintWindow(EL.reportTitle, locale, html);
    } catch {
      /* routine report unavailable */
    } finally {
      setPrintingId(null);
    }
  }

  if (loading) {
    return (
      <div>
        <PageHeader title={t.me.examsTitle} subtitle={t.me.examsSubtitle} />
        <LoadingArea label={t.common.loading} />
      </div>
    );
  }

  const exams = data?.exams ?? [];

  return (
    <div>
      <PageHeader title={t.me.examsTitle} subtitle={t.me.examsSubtitle} />

      {exams.length === 0 ? (
        <div className="card">
          <EmptyState icon={<IconCalendar />} title={t.me.noRoutines} />
        </div>
      ) : (
        exams.map((e) => {
          const today = new Date().toISOString().slice(0, 10);
          return (
          <Card
            title={locale === "bn" && e.nameBn ? e.nameBn : e.name}
            icon={<IconCalendar className="svg-20" />}
            key={e.id}
            action={
              <div className="d-flex align-items-center gap-2">
                <Button size="sm" variant="secondary" loading={printingId === e.id} onClick={() => printRoutine(e)}>
                  <IconFile className="svg-14" />
                  <span className="ms-1 d-none d-md-inline">{t.me.printRoutine}</span>
                </Button>
                <Button size="sm" variant="secondary" onClick={() => openAdmitCard(e.id)}>
                  <IconClipboard className="svg-14" />
                  <span className="ms-1 d-none d-md-inline">{t.me.admitCardBtn}</span>
                </Button>
              </div>
            }
          >
            <p className="ems-fs-12 text-muted mb-3">
              {formatDate(e.startDate, locale)}
              {e.endDate ? ` → ${formatDate(e.endDate, locale)}` : ""}
              {e.className ? ` · ${locale === "bn" && e.classNameBn ? e.classNameBn : e.className}` : ""}
              {e.resultPublished ? ` · ${t.me.resultPublishedBadge}` : ""}
            </p>
            {e.note && <p className="ems-fs-12 text-warning mb-3">{e.note}</p>}
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th>{t.common.date}</th>
                    <th>{t.me.time}</th>
                    <th>{t.me.subjectCol}</th>
                    <th>{t.me.roomCol}</th>
                    <th className="text-center">{t.me.fullMarksCol}</th>
                    <th className="text-center">{t.me.passMarksCol}</th>
                  </tr>
                </thead>
                <tbody>
                  {e.schedules.map((s) => {
                    const isToday = s.date.slice(0, 10) === today;
                    return (
                      <tr key={s.id} className={isToday ? "table-primary" : ""}>
                        <td className="f-w-600 ems-fs-13">
                          {formatDate(s.date, locale)}
                          {isToday && <span className="badge badge-success ms-1">{t.me.examToday}</span>}
                        </td>
                        <td className="ems-fs-12 text-muted">
                          {s.startTime ? `${s.startTime.slice(0, 5)}${s.endTime ? ` – ${s.endTime.slice(0, 5)}` : ""}` : "—"}
                        </td>
                        <td className="f-w-600 ems-fs-13">
                          {locale === "bn" && s.subjectItem?.nameBn ? s.subjectItem.nameBn : s.subjectItem?.name ?? "—"}
                        </td>
                        <td className="ems-fs-13">
                          {locale === "bn" && s.roomItem?.nameBn ? s.roomItem.nameBn : s.roomItem?.name ?? "—"}
                        </td>
                        <td className="text-center ems-fs-13">{s.fullMarks}</td>
                        <td className="text-center ems-fs-13">{s.totalPassMarks ?? "—"}</td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </Card>
          );
        })
      )}

      {/* Admit card modal — live preview + print (same builder as the portal) */}
      <Modal open={admitOpen} onClose={() => setAdmitOpen(false)} title={t.me.admitCardTitle} wide>
        <div style={{ background: "#f4f7fa", margin: "-1rem", padding: "1rem" }}>
          <div className="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
            <div className="btn-group btn-group-sm">
              {(["minimal", "detailed"] as AdmitVariant[]).map((v) => (
                <button
                  key={v}
                  type="button"
                  className={`btn f-w-700 ${admitVariant === v ? "btn-primary" : "btn-outline-secondary"}`}
                  onClick={() => setAdmitVariant(v)}
                >
                  {v === "minimal" ? L.variantMinimal : L.variantDetailed}
                </button>
              ))}
            </div>
            <Button size="sm" disabled={!admit} onClick={printAdmitCard}>
              <IconClipboard className="svg-14" />
              <span className="ms-1">{t.portal.certificatesPage.print}</span>
            </Button>
          </div>
          {admitLoading ? (
            <LoadingArea label={t.common.loading} />
          ) : admit && admitHtml ? (
            <div style={{ background: "#fff", borderRadius: 10, padding: 14, boxShadow: "0 4px 14px rgba(0,0,0,.06)", overflowX: "auto" }} dangerouslySetInnerHTML={{ __html: admitHtml }} />
          ) : (
            <EmptyState icon={<IconClipboard />} title={t.me.admitCardUnavailable} />
          )}
        </div>
      </Modal>
    </div>
  );
}
