"use client";

import { useMemo, useRef, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  EmptyState,
  Modal,
  PageHeader,
  PageLoader,
  Pagination,
  Select,
  StatCard,
  StatusBadge,
  TimePicker,
  usePagination,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatDate, formatTime } from "@/lib/utils";
import { WEEK_DAYS } from "@/lib/constants";
import { emsConfirm } from "@/components/ConfirmDialog";
import {
  IconCalendar,
  IconCheck,
  IconClock,
  IconEdit,
  IconFile,
  IconPlus,
  IconTrash,
  IconUsers,
} from "@/components/icons";

interface ScheduleRow {
  id: number;
  staffId: number | null;
  teacherName: string | null;
  sessionItemId: number | null;
  sessionName: string | null;
  departmentItemId: number | null;
  departmentName: string | null;
  classItemId: number | null;
  className: string | null;
  sectionItemId: number | null;
  sectionName: string | null;
  groupItemId: number | null;
  groupName: string | null;
  subjectItemId: number | null;
  subjectName: string | null;
  roomItemId: number | null;
  roomName: string | null;
  days: string[];
  startTime: string;
  endTime: string;
  note: string | null;
  isActive: boolean;
}

interface ScheduleData {
  summary: { total: number; active: number; classes: number; teachers: number };
  schedules: ScheduleRow[];
}

interface AcademicItem {
  id: number;
  category: string;
  name: string;
  nameBn: string;
}

interface StaffMini {
  id: number;
  employeeCode: string;
  name: string;
  designation: string;
  status: string;
}

type Tab = "schedules" | "routine";

const emptyForm = {
  staffId: "",
  sessionItemId: "",
  departmentItemId: "",
  classItemId: "",
  sectionItemId: "",
  groupItemId: "",
  subjectItemId: "",
  roomItemId: "",
  startTime: "10:00",
  endTime: "11:00",
  note: "",
  isActive: true,
};

export default function PortalSchedulePage() {
  const { t, locale } = useLang();
  const [tab, setTab] = useState<Tab>("schedules");
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  const { data, loading, reload } = useApi<ScheduleData>("/api/portal/schedule");
  const { data: academicData } = useApi<{ items: AcademicItem[]; selectedIds: number[] }>(
    "/api/portal/academic"
  );
  const { data: hrData } = useApi<{ staff: StaffMini[] }>("/api/portal/hr");
  const { data: meData } = useApi<{ user: { institution?: { name: string } | null } }>("/api/auth/me");
  // full institution details for the report header (logo, address, contacts)
  const { data: profileData } = useApi<{
    institution: {
      name: string; logo: string | null; address: string | null; phone: string | null;
      email: string | null; website: string | null; eiin: string | null; boardCode: string | null;
      educationBoard: string | null; establishedYear: number | null;
    } | null;
  }>("/api/portal/profile");
  // on-screen report preview (iframe) — Print runs from inside the preview
  const [preview, setPreview] = useState<{ title: string; html: string } | null>(null);
  const previewFrame = useRef<HTMLIFrameElement>(null);

  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<ScheduleRow | null>(null);
  const [form, setForm] = useState(emptyForm);
  const [days, setDays] = useState<string[]>([]);
  const [saving, setSaving] = useState(false);

  const [classFilter, setClassFilter] = useState("");
  const [routineClass, setRoutineClass] = useState("");
  const [routineTeacher, setRoutineTeacher] = useState("");

  const selectedItems = useMemo(() => {
    if (!academicData) return {} as Record<string, AcademicItem[]>;
    const selected = new Set(academicData.selectedIds);
    const byCat: Record<string, AcademicItem[]> = {};
    for (const item of academicData.items) {
      if (!selected.has(item.id)) continue;
      (byCat[item.category] ??= []).push(item);
    }
    return byCat;
  }, [academicData]);

  const teachers = (hrData?.staff ?? []).filter((s) => s.status === "ACTIVE");

  const schedules = useMemo(() => {
    if (!data) return [];
    return classFilter
      ? data.schedules.filter((s) => s.classItemId === Number(classFilter))
      : data.schedules;
  }, [data, classFilter]);

  const schedulesPager = usePagination(schedules, 10);

  // Weekly grid for the routine view: rows = time slots, columns = days
  const routine = useMemo(() => {
    if (!data || !routineClass) return null;
    const rows = data.schedules.filter(
      (s) => s.isActive && s.classItemId === Number(routineClass)
    );
    if (rows.length === 0) return null;
    const slots = [
      ...new Set(rows.map((r) => `${r.startTime}-${r.endTime}`)),
    ].sort();
    return {
      slots,
      cells: slots.map((slot) => {
        const [start, end] = slot.split("-");
        const cell: Record<string, ScheduleRow[]> = {};
        for (const r of rows.filter(
          (x) => x.startTime === start && x.endTime === end
        )) {
          for (const d of r.days) (cell[d] ??= []).push(r);
        }
        return { start, end, cell };
      }),
    };
  }, [data, routineClass]);

  // Weekly grid for the teacher time table: same layout, filtered by teacher
  const teacherRoutine = useMemo(() => {
    if (!data || !routineTeacher) return null;
    const rows = data.schedules.filter(
      (s) => s.isActive && s.staffId === Number(routineTeacher)
    );
    if (rows.length === 0) return null;
    const slots = [
      ...new Set(rows.map((r) => `${r.startTime}-${r.endTime}`)),
    ].sort();
    return {
      slots,
      cells: slots.map((slot) => {
        const [start, end] = slot.split("-");
        const cell: Record<string, ScheduleRow[]> = {};
        for (const r of rows.filter(
          (x) => x.startTime === start && x.endTime === end
        )) {
          for (const d of r.days) (cell[d] ??= []).push(r);
        }
        return { start, end, cell };
      }),
    };
  }, [data, routineTeacher]);

  function notify(type: "success" | "error", text: string) {
    setMessage({ type, text });
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function openCreate() {
    setEditing(null);
    setForm(emptyForm);
    setDays([]);
    setFormOpen(true);
  }

  function openEdit(s: ScheduleRow) {
    const id = (v: number | null) => (v ? String(v) : "");
    setEditing(s);
    setForm({
      staffId: id(s.staffId),
      sessionItemId: id(s.sessionItemId),
      departmentItemId: id(s.departmentItemId),
      classItemId: id(s.classItemId),
      sectionItemId: id(s.sectionItemId),
      groupItemId: id(s.groupItemId),
      subjectItemId: id(s.subjectItemId),
      roomItemId: id(s.roomItemId),
      startTime: s.startTime,
      endTime: s.endTime,
      note: s.note ?? "",
      isActive: s.isActive,
    });
    setDays(s.days);
    setFormOpen(true);
  }

  async function save() {
    setSaving(true);
    try {
      const payload = { ...form, days };
      if (editing) {
        await api(`/api/portal/schedule/${editing.id}`, {
          method: "PUT",
          body: JSON.stringify(payload),
        });
        notify("success", t.portal.schedulePage.scheduleUpdated);
      } else {
        await api("/api/portal/schedule", {
          method: "POST",
          body: JSON.stringify(payload),
        });
        notify("success", t.portal.schedulePage.scheduleCreated);
      }
      setFormOpen(false);
      reload();
    } catch (e) {
      const err = e instanceof Error ? e.message : "";
      notify(
        "error",
        err === "DAYS_REQUIRED"
          ? t.portal.schedulePage.daysRequired
          : err === "TIME_INVALID"
            ? t.portal.schedulePage.timeInvalid
            : err === "CONFLICT_TEACHER"
              ? t.portal.schedulePage.conflictTeacher
              : err === "CONFLICT_ROOM"
                ? t.portal.schedulePage.conflictRoom
                : err === "CONFLICT_CLASS"
                  ? t.portal.schedulePage.conflictClass
                  : t.common.tryAgain
      );
    } finally {
      setSaving(false);
    }
  }

  async function remove(s: ScheduleRow) {
    if (!(await emsConfirm({ message: t.common.confirmDelete, danger: true }))) return;
    try {
      await api(`/api/portal/schedule/${s.id}`, { method: "DELETE" });
      notify("success", t.common.deletedSuccessfully);
      reload();
    } catch {
      notify("error", t.common.tryAgain);
    }
  }

  /** Branded report shell — institution header (logo, name, address,
      EIIN/board) + teal title band, matching the system's other printable
      reports. `landscape` widens the @page for the weekly grids. */
  function buildReportHtml(title: string, subtitle: string, bodyHtml: string, landscape = false) {
    const inst = profileData?.institution ?? null;
    const instName = inst?.name ?? meData?.user?.institution?.name ?? "IncrelogEMS";
    const initials = instName
      .split(" ")
      .map((w) => w[0])
      .slice(0, 2)
      .join("")
      .toUpperCase();
    const contact = [
      inst?.address,
      inst?.phone ? `☎ ${inst.phone}` : null,
      inst?.email,
      inst?.eiin ? `EIIN: ${inst.eiin}` : inst?.boardCode ? `Code: ${inst.boardCode}` : null,
    ].filter(Boolean).join(" · ");
    return `<!DOCTYPE html>
<html lang="${locale}">
<head>
<meta charset="utf-8"/>
<title>${title}</title>
<style>
  @page { size: A4 ${landscape ? "landscape" : "portrait"}; margin: 10mm; }
  * { box-sizing: border-box; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  body { font-family: 'Montserrat', 'Noto Sans Bengali', sans-serif; color: #2c323f; margin: 0; padding: 18px; background: #fff; }
  .rpt-head { display: flex; align-items: center; gap: 12px; border-bottom: 3px solid #24695c; padding-bottom: 10px; }
  .rpt-head img.logo { width: 56px; height: 56px; object-fit: contain; }
  .rpt-head .initials { width: 56px; height: 56px; border-radius: 50%; background: #24695c; color: #fff; font-weight: 800; font-size: 20px; display: flex; align-items: center; justify-content: center; }
  .rpt-head h1 { font-size: 19px; margin: 0; color: #1a4a40; }
  .rpt-head .contact { margin: 3px 0 0; font-size: 10.5px; color: #6b7a88; }
  .rpt-band { background: #24695c; color: #fff; text-align: center; font-weight: 700; padding: 7px 12px; font-size: 13.5px; border-radius: 5px; margin: 12px 0 10px; letter-spacing: 0.6px; }
  .rpt-sub { color: #718096; font-size: 11.5px; margin: 0 0 12px; text-align: center; }
  h2 { font-size: 14px; margin: 18px 0 6px; color: #24695c; }
  table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
  th, td { border: 1px solid #d9e1ec; padding: 5px 9px; vertical-align: top; }
  th { background: #eef6f3; color: #1a4a40; text-align: left; font-weight: 700; }
  table.grid th, table.grid td { text-align: center; }
  table.grid td.time { white-space: nowrap; font-weight: 700; text-align: left; }
  td span.muted { color: #718096; font-size: 10.5px; }
  .foot { margin-top: 18px; font-size: 10.5px; color: #718096; display: flex; justify-content: space-between; }
</style>
</head>
<body>
  <div class="rpt-head">
    ${inst?.logo ? `<img class="logo" src="${inst.logo}" alt="" />` : `<div class="initials">${initials}</div>`}
    <div style="min-width: 0">
      <h1>${instName}</h1>
      ${contact ? `<p class="contact">${contact}</p>` : ""}
    </div>
  </div>
  <div class="rpt-band">${title}</div>
  ${subtitle ? `<p class="rpt-sub">${subtitle}</p>` : ""}
${bodyHtml}
  <div class="foot"><span>${instName}</span><span>IncrelogEMS</span></div>
</body>
</html>`;
  }

  /** Open the on-screen preview — printing runs from the preview's Print
      button (iframe print keeps the report's own styles). */
  function openPreview(title: string, html: string) {
    setPreview({ title, html });
  }

  function routineReportHead(reportTitle: string) {
    const L = t.portal.schedulePage;
    const cls = cat("CLASS").find((c) => String(c.id) === routineClass);
    const clsName = cls ? (locale === "bn" ? cls.nameBn : cls.name) : "—";
    const subtitle = `${L.routineFor} ${clsName} | ${L.generatedOn}: ${formatDate(new Date().toISOString(), locale)}`;
    return { L, clsName, subtitle };
  }

  /** Preview the weekly routine grid exactly as shown in the Routine View. */
  function printRoutineReport() {
    if (!routine) return;
    const { L, clsName, subtitle } = routineReportHead(t.portal.schedulePage.routineReport);
    const cellHtml = (r: ScheduleRow) =>
      `<b>${r.subjectName ?? "—"}</b><br><span class="muted">${[r.teacherName, r.roomName, r.sectionName, r.groupName].filter(Boolean).join(" · ")}</span>`;
    const body = `<table class="grid">
    <thead><tr><th>${L.timeLabel}</th>${WEEK_DAYS.map((d) => `<th>${t.days[d]}</th>`).join("")}</tr></thead>
    <tbody>
      ${routine.cells
        .map(
          ({ start, end, cell }) => `<tr>
        <td class="time">${formatTime(start, locale)}<br>– ${formatTime(end, locale)}</td>
        ${WEEK_DAYS.map((d) => `<td>${(cell[d] ?? []).map(cellHtml).join("<br>") || "—"}</td>`).join("")}
      </tr>`,
        )
        .join("")}
    </tbody>
  </table>`;
    openPreview(`${L.routineReport} — ${clsName}`, buildReportHtml(t.portal.schedulePage.routineReport, subtitle, body, true));
  }

  /** Preview a day-wise routine: one section per day (Saturday, Sunday, …). */
  function printDayRoutineReport() {
    if (!routine) return;
    const { L, clsName, subtitle } = routineReportHead(t.portal.schedulePage.dayBasisReport);
    const sections = WEEK_DAYS.map((d) => ({
      day: d,
      entries: routine.cells
        .flatMap(({ cell }) => cell[d] ?? [])
        .sort((a, b) => a.startTime.localeCompare(b.startTime)),
    })).filter((x) => x.entries.length > 0);
    const body = `${sections
      .map(
        ({ day, entries }) => `
  <h2>${t.days[day]}</h2>
  <table>
    <thead><tr><th>${L.timeLabel}</th><th>${L.subjectLabel}</th><th>${L.teacherLabel}</th><th>${L.roomNo}</th><th>${t.categories.SECTION}</th></tr></thead>
    <tbody>
      ${entries
        .map(
          (r) => `<tr>
        <td class="time" style="white-space:nowrap">${formatTime(r.startTime, locale)} – ${formatTime(r.endTime, locale)}</td>
        <td><b>${r.subjectName ?? "—"}</b></td>
        <td>${r.teacherName ?? "—"}</td>
        <td>${r.roomName ?? "—"}</td>
        <td>${[r.sectionName, r.groupName].filter(Boolean).join(" · ") || "—"}</td>
      </tr>`,
        )
        .join("")}
    </tbody>
  </table>`,
      )
      .join("")}`;
    openPreview(`${L.dayBasisReport} — ${clsName}`, buildReportHtml(t.portal.schedulePage.dayBasisReport, subtitle, body));
  }

  /** Preview a teacher's weekly time table — routine-view grid format, with the
      teacher's classes across all classes/sections (subject + class · room). */
  function printTeacherTimetable() {
    if (!teacherRoutine) return;
    const L = t.portal.schedulePage;
    const teacher = teachers.find((x) => String(x.id) === routineTeacher);
    const teacherName = teacher?.name ?? "—";
    const cellHtml = (r: ScheduleRow) =>
      `<b>${r.subjectName ?? "—"}</b><br><span class="muted">${[r.className, r.sectionName, r.groupName, r.roomName].filter(Boolean).join(" · ")}</span>`;
    const body = `<table class="grid">
    <thead><tr><th>${L.timeLabel}</th>${WEEK_DAYS.map((d) => `<th>${t.days[d]}</th>`).join("")}</tr></thead>
    <tbody>
      ${teacherRoutine.cells
        .map(
          ({ start, end, cell }) => `<tr>
        <td class="time">${formatTime(start, locale)}<br>– ${formatTime(end, locale)}</td>
        ${WEEK_DAYS.map((d) => `<td>${(cell[d] ?? []).map(cellHtml).join("<br>") || "—"}</td>`).join("")}
      </tr>`,
        )
        .join("")}
    </tbody>
  </table>`;
    const subtitle = `${teacherName} | ${L.generatedOn}: ${formatDate(new Date().toISOString(), locale)}`;
    openPreview(`${L.teacherTimetableReport} — ${teacherName}`, buildReportHtml(L.teacherTimetableReport, subtitle, body, true));
  }

  if (loading) return <PageLoader text={t.common.loading} />;
  const s = data?.summary;
  const cat = (key: string) => selectedItems[key] ?? [];

  return (
    <div>
      <PageHeader
        title={t.portal.schedulePage.title}
        subtitle={t.portal.schedulePage.subtitle}
        action={
          <Button onClick={openCreate}>
            <IconPlus className="svg-16" />
            <span className="ms-1">{t.portal.schedulePage.newSchedule}</span>
          </Button>
        }
      />

      {message && (
        <div className="mb-4">
          <Alert type={message.type} onClose={() => setMessage(null)}>{message.text}</Alert>
        </div>
      )}

      {/* Stats */}
      <div className="row g-3 mb-4">
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.schedulePage.totalSchedules} value={String(s?.total ?? 0)} icon={<IconCalendar />} accent="teal" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.schedulePage.activeSchedules} value={String(s?.active ?? 0)} icon={<IconCheck />} accent="blue" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.schedulePage.classesCovered} value={String(s?.classes ?? 0)} icon={<IconCalendar />} accent="purple" />
        </div>
        <div className="col-xl-3 col-sm-6">
          <StatCard label={t.portal.schedulePage.teachersInvolved} value={String(s?.teachers ?? 0)} icon={<IconUsers />} accent="orange" />
        </div>
      </div>

      {/* Tabs */}
      <ul className="nav nav-tabs mb-4" role="tablist">
        {(["schedules", "routine"] as Tab[]).map((key) => {
          const labels: Record<Tab, string> = {
            schedules: t.portal.schedulePage.tabSchedules,
            routine: t.portal.schedulePage.tabRoutine,
          };
          return (
            <li className="nav-item" key={key}>
              <button
                className={`nav-link ${tab === key ? "active" : ""}`}
                onClick={() => setTab(key)}
                type="button"
              >
                {labels[key]}
              </button>
            </li>
          );
        })}
      </ul>

      {/* ---------- Schedules tab ---------- */}
      {tab === "schedules" && (
        !data || data.schedules.length === 0 ? (
          <div className="card">
            <EmptyState
              icon={<IconCalendar />}
              title={t.portal.schedulePage.noSchedules}
              action={
                <Button onClick={openCreate}>
                  <IconPlus className="svg-16" />
                  <span className="ms-1">{t.portal.schedulePage.newSchedule}</span>
                </Button>
              }
            />
          </div>
        ) : (
          <div className="card">
            <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
              <div className="has-search d-flex align-items-center gap-2" style={{ maxWidth: 340 }}>
                <Select
                  wrapperClassName="form-group mb-0"
                  value={classFilter}
                  onChange={(e) => setClassFilter(e.target.value)}
                >
                  <option value="">{t.portal.schedulePage.allClasses}</option>
                  {cat("CLASS").map((c) => (
                    <option key={c.id} value={c.id}>
                      {locale === "bn" ? c.nameBn : c.name}
                    </option>
                  ))}
                </Select>
              </div>
              <Button onClick={openCreate}>
                <IconPlus className="svg-16" />
                <span className="ms-1">{t.portal.schedulePage.newSchedule}</span>
              </Button>
            </div>
            {schedules.length === 0 ? (
              <EmptyState title={t.common.noData} />
            ) : (
              <div className="table-responsive">
                <table className="table table-hover align-middle mb-0">
                  <thead className="ems-table-head">
                    <tr>
                      <th>{t.categories.CLASS}</th>
                      <th>{t.categories.SUBJECT}</th>
                      <th>{t.portal.schedulePage.teacherLabel}</th>
                      <th>{t.portal.schedulePage.timeLabel}</th>
                      <th>{t.portal.schedulePage.daysLabel}</th>
                      <th>{t.portal.schedulePage.roomNo}</th>
                      <th>{t.common.status}</th>
                      <th className="text-end">{t.common.actions}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {schedulesPager.paged.map((r) => (
                      <tr key={r.id} className={!r.isActive ? "opacity-50" : ""}>
                        <td>
                          <p className="mb-0 f-w-700">{r.className ?? "—"}</p>
                          {r.sectionName && (
                            <p className="mb-0 ems-fs-11 text-muted">
                              {t.categories.SECTION}: {r.sectionName}
                              {r.groupName ? ` · ${r.groupName}` : ""}
                            </p>
                          )}
                        </td>
                        <td className="f-w-600">{r.subjectName ?? "—"}</td>
                        <td className="ems-fs-13">{r.teacherName ?? "—"}</td>
                        <td className="ems-fs-13 f-w-600">
                          {formatTime(r.startTime, locale)} – {formatTime(r.endTime, locale)}
                        </td>
                        <td>
                          <div className="d-flex flex-wrap gap-1" style={{ maxWidth: 180 }}>
                            {r.days.map((d) => (
                              <span key={d} className="badge badge-secondary ems-fs-11">
                                {t.days[d as keyof typeof t.days].slice(0, locale === "bn" ? 3 : 3)}
                              </span>
                            ))}
                          </div>
                        </td>
                        <td className="ems-fs-13">{r.roomName ?? "—"}</td>
                        <td>
                          <StatusBadge
                            status={r.isActive ? "ACTIVE" : "INACTIVE"}
                            label={r.isActive ? t.common.active : t.common.inactive}
                          />
                        </td>
                        <td className="text-end">
                          <button className="btn btn-soft-secondary btn-sm me-1" onClick={() => openEdit(r)} type="button">
                            <IconEdit className="svg-16" />
                          </button>
                          <button className="btn btn-soft-danger btn-sm" onClick={() => remove(r)} type="button">
                            <IconTrash className="svg-16" />
                          </button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}
            <Pagination {...schedulesPager} onPageChange={schedulesPager.setPage} onSizeChange={schedulesPager.setSize} />
          </div>
        )
      )}

      {/* ---------- Routine view tab ---------- */}
      {tab === "routine" && (
        <Card
          title={t.portal.schedulePage.tabRoutine}
          icon={<IconClock className="svg-18" />}
          action={
            <div className="d-flex flex-wrap align-items-center gap-2">
              <div style={{ maxWidth: 220 }}>
                <Select
                  wrapperClassName="form-group mb-0"
                  value={routineClass}
                  onChange={(e) => setRoutineClass(e.target.value)}
                >
                  <option value="">{t.portal.schedulePage.selectClassView}</option>
                  {cat("CLASS").map((c) => (
                    <option key={c.id} value={c.id}>
                      {locale === "bn" ? c.nameBn : c.name}
                    </option>
                  ))}
                </Select>
              </div>
              <Button size="sm" variant="secondary" disabled={!routine} onClick={printRoutineReport}>
                <IconFile className="svg-16" />
                <span className="ms-1">{t.portal.schedulePage.printRoutine}</span>
              </Button>
              <Button size="sm" variant="secondary" disabled={!routine} onClick={printDayRoutineReport}>
                <IconFile className="svg-16" />
                <span className="ms-1">{t.portal.schedulePage.dayBasisReport}</span>
              </Button>
              <div style={{ maxWidth: 220 }}>
                <Select
                  wrapperClassName="form-group mb-0"
                  value={routineTeacher}
                  onChange={(e) => setRoutineTeacher(e.target.value)}
                >
                  <option value="">{t.portal.schedulePage.selectTeacher}</option>
                  {teachers.map((x) => (
                    <option key={x.id} value={x.id}>
                      {x.employeeCode} — {x.name}
                    </option>
                  ))}
                </Select>
              </div>
              <Button size="sm" variant="secondary" disabled={!teacherRoutine} onClick={printTeacherTimetable}>
                <IconFile className="svg-16" />
                <span className="ms-1">{t.portal.schedulePage.teacherTimetable}</span>
              </Button>
            </div>
          }
        >
          {!routineClass || !routine ? (
            <EmptyState
              icon={<IconCalendar />}
              title={routineClass ? t.portal.schedulePage.noRoutine : t.portal.schedulePage.selectClassView}
            />
          ) : (
            <div className="table-responsive">
              <table className="table table-bordered align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th style={{ minWidth: 120 }}>{t.portal.schedulePage.timeLabel}</th>
                    {WEEK_DAYS.map((d) => (
                      <th key={d} className="text-center">
                        {t.days[d]}
                      </th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {routine.cells.map(({ start, end, cell }) => (
                    <tr key={`${start}-${end}`}>
                      <td className="f-w-700 ems-fs-12 text-nowrap">
                        {formatTime(start, locale)}
                        <br />– {formatTime(end, locale)}
                      </td>
                      {WEEK_DAYS.map((d) => (
                        <td key={d} className="align-top">
                          {(cell[d] ?? []).map((r, i) => (
                            <div
                              key={r.id}
                              className={`rounded p-2 mb-${i === (cell[d] ?? []).length - 1 ? "0" : "1"}`}
                              style={{ background: "rgba(36,105,92,0.07)" }}
                            >
                              <p className="mb-0 ems-fs-12 f-w-700 ems-text-teal">{r.subjectName}</p>
                              <p className="mb-0 ems-fs-11 text-muted">
                                {r.teacherName}
                                {r.roomName ? ` · ${r.roomName}` : ""}
                                {r.sectionName ? ` · ${r.sectionName}` : ""}
                              </p>
                            </div>
                          ))}
                        </td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </Card>
      )}

      {/* Create / edit modal — mirrors the class schedule form */}
      <Modal
        open={formOpen}
        onClose={() => setFormOpen(false)}
        title={editing ? t.portal.schedulePage.editSchedule : t.portal.schedulePage.newSchedule}
        wide
      >
        <div className="row">
          <div className="col-md-6">
            <Select label={t.portal.schedulePage.teacherLabel} value={form.staffId} onChange={(e) => setForm({ ...form, staffId: e.target.value })}>
              <option value="">— {t.common.filter} —</option>
              {teachers.map((t2) => (
                <option key={t2.id} value={t2.id}>
                  {t2.employeeCode} — {t2.name}
                </option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.portal.schedulePage.sessionLabel} value={form.sessionItemId} onChange={(e) => setForm({ ...form, sessionItemId: e.target.value })}>
              <option value="">—</option>
              {cat("SESSION").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.portal.schedulePage.departmentLabel} value={form.departmentItemId} onChange={(e) => setForm({ ...form, departmentItemId: e.target.value })}>
              <option value="">—</option>
              {cat("DEPARTMENT").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.portal.schedulePage.subjectLabel} value={form.subjectItemId} onChange={(e) => setForm({ ...form, subjectItemId: e.target.value })}>
              <option value="">— {t.common.filter} —</option>
              {cat("SUBJECT").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.categories.CLASS} value={form.classItemId} onChange={(e) => setForm({ ...form, classItemId: e.target.value })}>
              <option value="">— {t.common.filter} —</option>
              {cat("CLASS").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.portal.schedulePage.roomNo} value={form.roomItemId} onChange={(e) => setForm({ ...form, roomItemId: e.target.value })}>
              <option value="">—</option>
              {cat("ROOM").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.categories.SECTION} value={form.sectionItemId} onChange={(e) => setForm({ ...form, sectionItemId: e.target.value })}>
              <option value="">—</option>
              {cat("SECTION").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <Select label={t.categories.GROUP} value={form.groupItemId} onChange={(e) => setForm({ ...form, groupItemId: e.target.value })}>
              <option value="">—</option>
              {cat("GROUP").map((i) => (
                <option key={i.id} value={i.id}>{locale === "bn" ? i.nameBn : i.name}</option>
              ))}
            </Select>
          </div>
          <div className="col-md-6">
            <TimePicker label={t.portal.schedulePage.startLabel} value={form.startTime} onChange={(e) => setForm({ ...form, startTime: e.target.value })} />
          </div>
          <div className="col-md-6">
            <TimePicker label={t.portal.schedulePage.endLabel} value={form.endTime} onChange={(e) => setForm({ ...form, endTime: e.target.value })} />
          </div>
        </div>

        {/* Days */}
        <label className="col-form-label pt-0 f-w-600">{t.portal.schedulePage.daysLabel}</label>
        <div className="row g-2 mb-3">
          {WEEK_DAYS.map((d) => (
            <div className="col-md-3 col-4" key={d}>
              <div className="form-check">
                <input
                  className="form-check-input"
                  type="checkbox"
                  id={`day-${d}`}
                  checked={days.includes(d)}
                  onChange={(e) =>
                    setDays(e.target.checked ? [...days, d] : days.filter((x) => x !== d))
                  }
                />
                <label className="form-check-label f-w-600 ems-fs-13" htmlFor={`day-${d}`}>
                  {t.days[d]}
                </label>
              </div>
            </div>
          ))}
        </div>

        <div className="form-group mb-3">
          <label className="col-form-label pt-0 f-w-600">{t.portal.schedulePage.noteLabel}</label>
          <textarea
            className="form-control"
            rows={2}
            value={form.note}
            onChange={(e) => setForm({ ...form, note: e.target.value })}
          />
        </div>

        <div className="d-flex align-items-center justify-content-between pt-2 border-top">
          <div className="form-check">
            <input
              className="form-check-input"
              type="checkbox"
              id="scheduleActive"
              checked={form.isActive}
              onChange={(e) => setForm({ ...form, isActive: e.target.checked })}
            />
            <label className="form-check-label f-w-600" htmlFor="scheduleActive">
              {t.portal.schedulePage.activeLabel}
            </label>
          </div>
          <div className="d-flex gap-2">
            <Button variant="secondary" onClick={() => setFormOpen(false)}>
              {t.common.cancel}
            </Button>
            <Button
              onClick={save}
              loading={saving}
              disabled={!form.staffId || !form.classItemId || !form.subjectItemId || days.length === 0}
            >
              {editing ? t.common.saveChanges : t.common.create}
            </Button>
          </div>
        </div>
      </Modal>

      {/* ---------- Report preview — on-screen A4 look, Print runs inside ---------- */}
      <Modal open={!!preview} onClose={() => setPreview(null)} title={t.portal.schedulePage.reportPreview} wide>
        <div className="rounded border" style={{ background: "#eef1f5", padding: 10, maxHeight: "68vh", overflow: "auto" }}>
          <iframe
            ref={previewFrame}
            title={preview?.title ?? "report"}
            srcDoc={preview?.html ?? ""}
            style={{ width: "100%", height: "64vh", border: 0, background: "#fff", borderRadius: 6, boxShadow: "0 8px 24px -12px rgba(16,42,36,0.25)" }}
          />
        </div>
        <div className="d-flex justify-content-end gap-2 mt-3">
          <Button variant="secondary" onClick={() => setPreview(null)}>{t.common.cancel}</Button>
          <Button onClick={() => previewFrame.current?.contentWindow?.print()}>{t.common.print}</Button>
        </div>
      </Modal>
    </div>
  );
}
