"use client";

import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
import { DeliveryChip } from "@/components/academic/attendance/AttendancePrimitives";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input } from "@/components/ui/Field";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { PersianDatePicker } from "@/components/ui/PersianDatePicker";
import { ClassAttendanceHistory } from "@/components/teacher/ClassAttendanceHistory";
import { useAttendanceCalendarMarks } from "@/components/teacher/useAttendanceCalendarMarks";
import { LateMinutesPicker } from "@/components/teacher/LateMinutesPicker";
import { StudentAvatar } from "@/components/teacher/StudentAvatar";
import { StudentQuickModal } from "@/components/teacher/StudentQuickModal";
import { TeacherModal } from "@/components/teacher/ui/TeacherModal";
import { TeacherPanel } from "@/components/teacher/ui/TeacherPanel";
import { TeacherStatGrid } from "@/components/teacher/ui/TeacherStatGrid";
import { ApiError, apiGet, apiPost } from "@/lib/api";
import {
  nearestSessionDate,
  nextSessionDate,
  previousSessionDate,
} from "@/lib/class-session-dates";
import type { DeliveryMode } from "@/lib/attendance-report";

type AttendanceStatus = "present" | "absent" | "late" | "temporary_exit" | null;

interface StudentRow {
  enrollment_id: number;
  student_profile_id?: number | null;
  first_name?: string | null;
  last_name?: string | null;
  student_code?: string | null;
  gate_entry_at?: string | null;
  attendance?: {
    status: string;
    late_minutes?: number | null;
    late_justified?: boolean;
    early_exit_justified?: boolean;
    note?: string | null;
  } | null;
}

interface AttendancePayload {
  students: StudentRow[];
  counts: { unchecked: number; present: number; late: number; absent: number; temporary_exit?: number };
  late_minute_presets?: number[];
  delivery_mode?: DeliveryMode | null;
  delivery_mode_label?: string | null;
  is_virtual?: boolean;
}

type LocalEntry = {
  status: AttendanceStatus;
  late_minutes: string;
  late_justified?: boolean;
  early_exit_justified?: boolean;
  note?: string;
};
type LocalState = Record<number, LocalEntry>;

type DetailItem = {
  name: string;
  status: string;
  minutes?: string;
  note?: string;
  justified?: boolean;
};

function nameOf(row: StudentRow) {
  const n = [row.first_name, row.last_name].filter(Boolean).join(" ");
  return n || row.student_code || `#${row.enrollment_id}`;
}

function statusLabel(st?: LocalEntry) {
  if (!st?.status) return "علامت‌گذاری نشده";
  if (st.status === "late") {
    const base = `تأخیر ${st.late_minutes || "?"} دقیقه`;
    return st.late_justified ? `${base} · موجه` : base;
  }
  if (st.status === "present") return "حاضر";
  if (st.status === "temporary_exit") {
    return st.early_exit_justified ? "تعجیل · موجه" : "تعجیل";
  }
  return "غایب";
}

function statusKindLabel(status: string) {
  if (status === "late") return "تأخیر";
  if (status === "absent") return "غیبت";
  if (status === "temporary_exit") return "تعجیل";
  if (status === "present") return "حاضر";
  return status;
}

function detailFromAttendance(row: StudentRow, overlay?: LocalEntry): DetailItem | null {
  const status = overlay?.status ?? (row.attendance?.status as AttendanceStatus) ?? null;
  if (!status) return null;
  const lateMinutes =
    overlay?.late_minutes ?? (row.attendance?.late_minutes ? String(row.attendance.late_minutes) : "");
  const note = (overlay?.note ?? row.attendance?.note ?? "").trim();
  const lateJustified = overlay?.late_justified ?? Boolean(row.attendance?.late_justified);
  const earlyJustified = overlay?.early_exit_justified ?? Boolean(row.attendance?.early_exit_justified);
  return {
    name: nameOf(row),
    status,
    minutes: status === "late" && lateMinutes ? lateMinutes : undefined,
    note: note || undefined,
    justified:
      status === "late" ? lateJustified : status === "temporary_exit" ? earlyJustified : undefined,
  };
}

function ActionCircle({
  title,
  className,
  disabled,
  onClick,
  children,
}: {
  title: string;
  className: string;
  disabled?: boolean;
  onClick: () => void;
  children: ReactNode;
}) {
  return (
    <button
      type="button"
      title={title}
      disabled={disabled}
      onClick={onClick}
      className={`inline-flex h-9 w-9 items-center justify-center rounded-full text-sm font-bold shadow-sm transition disabled:opacity-50 ${className}`}
    >
      {children}
    </button>
  );
}

function todayIso() {
  return new Date().toISOString().slice(0, 10);
}

function shiftDate(iso: string, delta: number) {
  const d = new Date(iso + "T12:00:00");
  d.setDate(d.getDate() + delta);
  return d.toISOString().slice(0, 10);
}

function formatFaDate(iso: string) {
  try {
    return new Date(iso + "T12:00:00").toLocaleDateString("fa-IR", {
      weekday: "long",
      year: "numeric",
      month: "long",
      day: "numeric",
    });
  } catch {
    return iso;
  }
}

export function ClassAttendanceTab({
  classRoomId,
  scheduleId,
  subjectId: subjectIdProp,
  attendanceDate,
}: {
  classRoomId: number;
  scheduleId?: number | null;
  subjectId?: number | null;
  attendanceDate?: string;
}) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const date = attendanceDate ?? todayIso();
  const subjectIdParam = searchParams.get("subject_id");
  const subjectId = subjectIdProp ?? (subjectIdParam ? Number(subjectIdParam) : null);

  const [calendarMonth, setCalendarMonth] = useState(() => date.slice(0, 7));

  const [data, setData] = useState<AttendancePayload | null>(null);
  const [local, setLocal] = useState<LocalState>({});
  const localRef = useRef<LocalState>({});
  const [lateFor, setLateFor] = useState<number | null>(null);
  const [absentFor, setAbsentFor] = useState<number | null>(null);
  const [absentNote, setAbsentNote] = useState("");
  const [earlyExitFor, setEarlyExitFor] = useState<number | null>(null);
  const [earlyExitNote, setEarlyExitNote] = useState("");
  const [earlyExitJustified, setEarlyExitJustified] = useState(false);
  const [detailModal, setDetailModal] = useState<{ title: string; items: DetailItem[] } | null>(null);
  const [editingIds, setEditingIds] = useState<Set<number>>(new Set());
  const [presets, setPresets] = useState<number[]>([5, 10, 15, 20, 30]);
  const [loading, setLoading] = useState(true);
  const [savingIds, setSavingIds] = useState<Set<number>>(new Set());
  const [bulkSaving, setBulkSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [flash, setFlash] = useState<string | null>(null);
  const [historyKey, setHistoryKey] = useState(0);
  const [quickStudentId, setQuickStudentId] = useState<number | null>(null);
  const [pastDateConfirmOpen, setPastDateConfirmOpen] = useState(false);
  const pastDateAckRef = useRef<string | null>(null);
  const pendingPastActionRef = useRef<(() => void) | null>(null);

  useEffect(() => {
    localRef.current = local;
  }, [local]);

  useEffect(() => {
    setCalendarMonth(date.slice(0, 7));
    pastDateAckRef.current = null;
    pendingPastActionRef.current = null;
    setPastDateConfirmOpen(false);
  }, [date]);

  const { sessionDates, allSessionDates, recordedDates, loading: calendarLoading } =
    useAttendanceCalendarMarks({
      classRoomId,
      scheduleId,
      subjectId,
      month: calendarMonth,
      anchorDate: date,
    });

  const hasSessionSchedule = allSessionDates.length > 0;
  const today = todayIso();
  const prevSession = hasSessionSchedule ? previousSessionDate(allSessionDates, date) : null;
  const nextSession = hasSessionSchedule ? nextSessionDate(allSessionDates, date, today) : null;
  const todaySession = hasSessionSchedule
    ? nearestSessionDate(allSessionDates, today, today)
    : today;

  const setDate = useCallback(
    (next: string) => {
      const params = new URLSearchParams(searchParams.toString());
      params.set("tab", "attendance");
      params.set("date", next);
      router.replace(`/teacher/classes/${classRoomId}?${params.toString()}`, { scroll: false });
    },
    [classRoomId, router, searchParams],
  );

  useEffect(() => {
    if (calendarLoading || !hasSessionSchedule) return;
    if (!allSessionDates.includes(date)) {
      const nearest = nearestSessionDate(allSessionDates, date, today);
      if (nearest && nearest !== date) setDate(nearest);
    }
  }, [allSessionDates, calendarLoading, date, hasSessionSchedule, setDate, today]);

  const pickDate = useCallback(
    (next: string) => {
      if (next > today) return;
      if (hasSessionSchedule && !allSessionDates.includes(next)) return;
      setDate(next);
    },
    [allSessionDates, hasSessionSchedule, setDate, today],
  );

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams({
        class_room_id: String(classRoomId),
        attendance_date: date,
      });
      if (scheduleId) params.set("schedule_id", String(scheduleId));
      if (subjectId) params.set("subject_id", String(subjectId));
      const payload = await apiGet<AttendancePayload>(`/class-attendances?${params}`);
      setData(payload);
      if (payload.late_minute_presets?.length) setPresets(payload.late_minute_presets);
      const init: LocalState = {};
      payload.students.forEach((s) => {
        init[s.enrollment_id] = {
          status: (s.attendance?.status as AttendanceStatus) ?? null,
          late_minutes: s.attendance?.late_minutes ? String(s.attendance.late_minutes) : "",
          late_justified: Boolean(s.attendance?.late_justified),
          early_exit_justified: Boolean(s.attendance?.early_exit_justified),
          note: s.attendance?.note ?? "",
        };
      });
      setLocal(init);
      setEditingIds(new Set());
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا");
    } finally {
      setLoading(false);
    }
  }, [classRoomId, date, scheduleId, subjectId]);

  useEffect(() => {
    void load();
  }, [load]);

  const counts = useMemo(() => {
    const vals = Object.values(local);
    return {
      pending: vals.filter((v) => !v.status).length,
      present: vals.filter((v) => v.status === "present").length,
      late: vals.filter((v) => v.status === "late").length,
      absent: vals.filter((v) => v.status === "absent").length,
      early: vals.filter((v) => v.status === "temporary_exit").length,
    };
  }, [local]);

  const persistEntries = useCallback(
    async (
      entries: Array<{
        enrollment_id: number;
        status: string;
        late_minutes?: number;
        late_justified?: boolean;
        early_exit_justified?: boolean;
        note?: string;
      }>,
      previous: LocalState,
    ) => {
      const ids = entries.map((e) => e.enrollment_id);
      setSavingIds((prev) => {
        const next = new Set(prev);
        ids.forEach((id) => next.add(id));
        return next;
      });
      setError(null);
      try {
        await apiPost(`/academic/attendance/class/${classRoomId}`, {
          attendance_date: date,
          schedule_id: scheduleId ?? null,
          subject_id: subjectId ?? null,
          entries,
        });
        setFlash("ثبت شد");
        setHistoryKey((k) => k + 1);
        window.setTimeout(() => setFlash(null), 1500);
      } catch (err) {
        setLocal(previous);
        setError(err instanceof ApiError ? err.message : "خطا در ذخیره");
      } finally {
        setSavingIds((prev) => {
          const next = new Set(prev);
          ids.forEach((id) => next.delete(id));
          return next;
        });
      }
    },
    [classRoomId, date, scheduleId, subjectId],
  );

  const saveOne = useCallback(
    async (
      id: number,
      status: Exclude<AttendanceStatus, null>,
      opts?: {
        lateMinutes?: number;
        lateJustified?: boolean;
        note?: string;
        earlyExitJustified?: boolean;
      },
    ) => {
      const previous = { ...localRef.current };
      const prevEntry = previous[id];
      const nextEntry: LocalEntry = {
        status,
        late_minutes:
          status === "late"
            ? String(opts?.lateMinutes ?? "")
            : status === "temporary_exit"
              ? prevEntry?.late_minutes ?? ""
              : "",
        late_justified:
          status === "late"
            ? Boolean(opts?.lateJustified)
            : status === "temporary_exit"
              ? Boolean(prevEntry?.late_justified)
              : false,
        early_exit_justified: status === "temporary_exit" ? Boolean(opts?.earlyExitJustified) : false,
        note: opts?.note ?? "",
      };
      setLocal((prev) => ({ ...prev, [id]: nextEntry }));
      setEditingIds((prev) => {
        const next = new Set(prev);
        next.delete(id);
        return next;
      });
      await persistEntries(
        [
          {
            enrollment_id: id,
            status,
            late_minutes: status === "late" ? opts?.lateMinutes : undefined,
            late_justified: status === "late" ? Boolean(opts?.lateJustified) : undefined,
            early_exit_justified: status === "temporary_exit" ? Boolean(opts?.earlyExitJustified) : undefined,
            note: opts?.note,
          },
        ],
        previous,
      );
    },
    [persistEntries],
  );

  const runOrConfirmPastDate = (action: () => void) => {
    if (date === todayIso() || pastDateAckRef.current === date) {
      action();
      return;
    }
    pendingPastActionRef.current = action;
    setPastDateConfirmOpen(true);
  };

  const confirmPastDateEdit = () => {
    pastDateAckRef.current = date;
    setPastDateConfirmOpen(false);
    const action = pendingPastActionRef.current;
    pendingPastActionRef.current = null;
    action?.();
  };

  const setStatus = (id: number, status: AttendanceStatus) => {
    runOrConfirmPastDate(() => {
      if (status === "late") {
        setLateFor(id);
        return;
      }
      if (status === "absent") {
        setAbsentFor(id);
        setAbsentNote("");
        return;
      }
      if (status === "temporary_exit") {
        setEarlyExitFor(id);
        setEarlyExitNote("");
        setEarlyExitJustified(false);
        return;
      }
      if (!status) return;
      void saveOne(id, status);
    });
  };

  const confirmLate = (minutes: number, justified: boolean, note: string) => {
    if (lateFor == null) return;
    const id = lateFor;
    setLateFor(null);
    void saveOne(id, "late", { lateMinutes: minutes, lateJustified: justified, note: note || undefined });
  };

  const confirmAbsent = () => {
    if (absentFor == null) return;
    const id = absentFor;
    const note = absentNote.trim();
    setAbsentFor(null);
    setAbsentNote("");
    void saveOne(id, "absent", { note: note || undefined });
  };

  const confirmEarlyExit = () => {
    if (earlyExitFor == null) return;
    const id = earlyExitFor;
    const note = earlyExitNote.trim();
    const justified = earlyExitJustified;
    setEarlyExitFor(null);
    setEarlyExitNote("");
    setEarlyExitJustified(false);
    void saveOne(id, "temporary_exit", {
      note: note || undefined,
      earlyExitJustified: justified,
    });
  };

  const markAllPresent = async () => {
    const previous = { ...localRef.current };
    const entries = Object.keys(previous).map((k) => ({
      enrollment_id: Number(k),
      status: "present" as const,
    }));
    if (entries.length === 0) return;

    setBulkSaving(true);
    setLocal((prev) => {
      const next = { ...prev };
      Object.keys(next).forEach((k) => {
        next[Number(k)] = {
          status: "present",
          late_minutes: "",
          late_justified: false,
          early_exit_justified: false,
          note: "",
        };
      });
      return next;
    });

    setError(null);
    try {
        await apiPost(`/academic/attendance/class/${classRoomId}`, {
          attendance_date: date,
          schedule_id: scheduleId ?? null,
          subject_id: subjectId ?? null,
          entries,
        });
      setFlash("همه حاضر ثبت شد");
      setHistoryKey((k) => k + 1);
      window.setTimeout(() => setFlash(null), 1500);
    } catch (err) {
      setLocal(previous);
      setError(err instanceof ApiError ? err.message : "خطا در ذخیره");
    } finally {
      setBulkSaving(false);
    }
  };

  const openStatusListForDate = useCallback(
    async (targetDate: string, status: Exclude<AttendanceStatus, null>) => {
      try {
        let students = data?.students ?? [];
        let overlay: LocalState | undefined = local;
        if (targetDate !== date) {
          const params = new URLSearchParams({
            class_room_id: String(classRoomId),
            attendance_date: targetDate,
          });
          if (scheduleId) params.set("schedule_id", String(scheduleId));
          if (subjectId) params.set("subject_id", String(subjectId));
          const payload = await apiGet<AttendancePayload>(`/class-attendances?${params}`);
          students = payload.students ?? [];
          overlay = undefined;
        }
        const items = students
          .map((row) => detailFromAttendance(row, overlay?.[row.enrollment_id]))
          .filter((item): item is DetailItem => item != null && item.status === status);
        setDetailModal({
          title: `${statusKindLabel(status)} · ${formatFaDate(targetDate)} · ${items.length} نفر`,
          items,
        });
      } catch (err) {
        setError(err instanceof ApiError ? err.message : "خطا در بارگذاری لیست");
      }
    },
    [classRoomId, data?.students, date, local, scheduleId, subjectId],
  );

  const openStudentReason = (row: StudentRow) => {
    const item = detailFromAttendance(row, local[row.enrollment_id]);
    if (!item) return;
    setDetailModal({ title: nameOf(row), items: [item] });
  };

  const recorded = recordedDates.includes(date);
  const classDayLabel = hasSessionSchedule
    ? new Date((todaySession || date) + "T12:00:00").toLocaleDateString("fa-IR", { weekday: "long" })
    : "—";

  const statItems = [
    { key: "pending", label: `در انتظار: ${counts.pending} نفر`, value: counts.pending, className: "border-sky-200 bg-sky-50/70", accent: "#0284c7", icon: "👥" },
    {
      key: "present",
      label: `حاضر: ${counts.present} نفر`,
      value: counts.present,
      className: "border-emerald-200 bg-emerald-50/70",
      accent: "#059669",
      icon: "✓",
      onClick: counts.present ? () => void openStatusListForDate(date, "present") : undefined,
    },
    {
      key: "late",
      label: `تأخیر: ${counts.late} نفر`,
      value: counts.late,
      className: "border-violet-200 bg-violet-50/70",
      accent: "#7c3aed",
      icon: "🕐",
      onClick: counts.late ? () => void openStatusListForDate(date, "late") : undefined,
    },
    {
      key: "absent",
      label: `غایب: ${counts.absent} نفر`,
      value: counts.absent,
      className: "border-orange-200 bg-orange-50/70",
      accent: "#ea580c",
      icon: "✕",
      onClick: counts.absent ? () => void openStatusListForDate(date, "absent") : undefined,
    },
    {
      key: "early",
      label: `تعجیل: ${counts.early} نفر`,
      value: counts.early,
      className: "border-amber-200 bg-amber-50/70",
      accent: "#d97706",
      icon: "↩",
      onClick: counts.early ? () => void openStatusListForDate(date, "temporary_exit") : undefined,
    },
  ];

  return (
    <div className="space-y-4">
      {error ? <Alert tone="error">{error}</Alert> : null}
      {flash ? <Alert tone="success">{flash}</Alert> : null}

      <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-slate-200 bg-white px-4 py-3 shadow-sm">
        <div className="text-sm font-semibold text-slate-800">
          {formatFaDate(date)}
          {hasSessionSchedule ? (
            <span className="mr-2 text-xs font-medium text-slate-500">روز کلاس: {classDayLabel}</span>
          ) : null}
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <DeliveryChip
            mode={data?.delivery_mode}
            label={data?.delivery_mode_label ?? undefined}
          />
          {recorded ? (
            <span className="rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-800">ثبت شده</span>
          ) : (
            <span className="rounded-full bg-slate-100 px-3 py-1 text-xs font-semibold text-slate-500">ثبت نشده</span>
          )}
          <div className="min-w-[148px]">
            <PersianDatePicker
              value={date}
              maxDate={today}
              sessionDates={hasSessionSchedule ? allSessionDates : sessionDates}
              recordedDates={recordedDates}
              restrictToSessionDates={hasSessionSchedule}
              onMonthChange={setCalendarMonth}
              onChange={(next) => {
                if (next) pickDate(next);
              }}
              className="h-9 rounded-xl border border-slate-200 px-3 text-sm text-slate-700"
            />
          </div>
          <Button
            variant="secondary"
            className={`h-9 rounded-xl px-3 ${prevSession ? "border-emerald-400 text-emerald-800" : ""}`}
            onClick={() => {
              if (hasSessionSchedule) {
                if (prevSession) pickDate(prevSession);
              } else {
                pickDate(shiftDate(date, -1));
              }
            }}
            disabled={hasSessionSchedule ? !prevSession : false}
          >
            {hasSessionSchedule ? "جلسه قبل" : "روز قبل"}
          </Button>
          <Button
            variant="secondary"
            className="h-9 rounded-xl px-3"
            onClick={() => pickDate(todaySession)}
            disabled={date === todaySession}
          >
            امروز
          </Button>
          <Button
            variant="secondary"
            className="h-9 rounded-xl px-3"
            onClick={() => {
              if (hasSessionSchedule) {
                if (nextSession) pickDate(nextSession);
              } else {
                pickDate(shiftDate(date, 1));
              }
            }}
            disabled={hasSessionSchedule ? !nextSession : date >= today}
          >
            {hasSessionSchedule ? "جلسه بعد" : "روز بعد"}
          </Button>
          <Button
            variant="secondary"
            className="h-9 rounded-xl px-3"
            onClick={() => pickDate(todaySession)}
          >
            روز کلاس
          </Button>
        </div>
      </div>

      <TeacherStatGrid items={statItems} />

      <div className="grid gap-4 lg:grid-cols-[1fr_260px]">
        <div>
          {loading ? (
            <PageContentSkeleton rows={5} />
          ) : (
            <TeacherPanel padded={false}>
              <div className="overflow-x-auto">
                <table className="min-w-full text-sm">
                  <thead className="bg-slate-50 text-slate-500">
                    <tr>
                      <th className="px-4 py-3 text-right font-semibold">نام دانش‌آموز</th>
                      <th className="px-4 py-3 text-right font-semibold">
                        <div className="flex flex-wrap items-center justify-start gap-2">
                          <span>عملیات</span>
                          <Button
                            variant="secondary"
                            className="h-8 rounded-xl px-3 text-xs"
                            onClick={() => runOrConfirmPastDate(() => void markAllPresent())}
                            loading={bulkSaving}
                          >
                            همه حاضر
                          </Button>
                        </div>
                      </th>
                    </tr>
                  </thead>
                  <tbody>
                    {(data?.students ?? []).map((row) => {
                      const st = local[row.enrollment_id];
                      const busy = savingIds.has(row.enrollment_id);
                      const badgeClass =
                        st?.status === "present"
                          ? "bg-emerald-100 text-emerald-800"
                          : st?.status === "absent"
                            ? "bg-orange-100 text-orange-800"
                            : st?.status === "late"
                              ? "bg-violet-100 text-violet-800"
                              : st?.status === "temporary_exit"
                                ? "bg-amber-100 text-amber-800"
                                : "bg-slate-100 text-slate-600";
                      const recordedStatus = Boolean(st?.status);
                      const editing = editingIds.has(row.enrollment_id);
                      const showChooser = !recordedStatus || editing;
                      const showEarlyExit =
                        !editing && (st?.status === "present" || st?.status === "late");
                      return (
                        <tr
                          key={row.enrollment_id}
                          className={`border-t border-slate-100 hover:bg-slate-50/70 ${busy ? "opacity-70" : ""}`}
                        >
                          <td className="px-4 py-3">
                            <button
                              type="button"
                              disabled={!row.student_profile_id}
                              onClick={() => {
                                if (row.student_profile_id) setQuickStudentId(row.student_profile_id);
                              }}
                              className="flex items-center gap-2.5 text-right font-medium text-slate-900 hover:text-primary disabled:cursor-default disabled:hover:text-slate-900"
                            >
                              <StudentAvatar firstName={row.first_name} lastName={row.last_name} size="sm" />
                              {nameOf(row)}
                            </button>
                          </td>
                          <td className="px-4 py-3">
                            {showChooser ? (
                              <div className="flex flex-wrap items-center gap-1.5">
                                <ActionCircle
                                  title="حاضر"
                                  disabled={busy || bulkSaving}
                                  className="bg-emerald-100 text-emerald-700 hover:bg-emerald-200"
                                  onClick={() => setStatus(row.enrollment_id, "present")}
                                >
                                  ✓
                                </ActionCircle>
                                <ActionCircle
                                  title="غایب"
                                  disabled={busy || bulkSaving}
                                  className="bg-red-100 text-red-700 hover:bg-red-200"
                                  onClick={() => setStatus(row.enrollment_id, "absent")}
                                >
                                  ✕
                                </ActionCircle>
                                <ActionCircle
                                  title="تأخیر"
                                  disabled={busy || bulkSaving}
                                  className="bg-violet-100 text-violet-800 hover:bg-violet-200"
                                  onClick={() => setStatus(row.enrollment_id, "late")}
                                >
                                  🕐
                                </ActionCircle>
                              </div>
                            ) : (
                              <div className="flex flex-wrap items-center gap-2">
                                {(st?.status === "late" || st?.status === "absent" || st?.status === "temporary_exit") ? (
                                  <button
                                    type="button"
                                    title={st?.note?.trim() ? "مشاهده دلیل" : statusLabel(st)}
                                    onClick={() => openStudentReason(row)}
                                    className={`inline-flex rounded-full px-2.5 py-1 text-xs font-semibold ${badgeClass} ${
                                      st?.note?.trim() ? "ring-1 ring-inset ring-black/10 hover:brightness-95" : "hover:brightness-95"
                                    }`}
                                  >
                                    {busy ? "…" : statusLabel(st)}
                                  </button>
                                ) : (
                                  <span className={`inline-flex rounded-full px-2.5 py-1 text-xs font-semibold ${badgeClass}`}>
                                    {busy ? "…" : statusLabel(st)}
                                  </span>
                                )}
                                {showEarlyExit ? (
                                  <Button
                                    variant="secondary"
                                    className="h-9 rounded-xl px-3 text-xs"
                                    disabled={busy || bulkSaving}
                                    onClick={() => setStatus(row.enrollment_id, "temporary_exit")}
                                  >
                                    خروج زودتر از موعد
                                  </Button>
                                ) : null}
                                <button
                                  type="button"
                                  className="text-xs font-medium text-slate-500 hover:text-slate-800"
                                  disabled={busy || bulkSaving}
                                  onClick={() =>
                                    setEditingIds((prev) => {
                                      const next = new Set(prev);
                                      next.add(row.enrollment_id);
                                      return next;
                                    })
                                  }
                                >
                                  تغییر
                                </button>
                              </div>
                            )}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            </TeacherPanel>
          )}
        </div>

        <ClassAttendanceHistory
          key={historyKey}
          classRoomId={classRoomId}
          scheduleId={scheduleId}
          subjectId={subjectId}
          selectedDate={date}
          onSelectDate={pickDate}
          onSelectSummary={(nextDate, status) => {
            void openStatusListForDate(nextDate, status);
          }}
        />
      </div>

      <LateMinutesPicker
        open={lateFor != null}
        onClose={() => setLateFor(null)}
        onConfirm={confirmLate}
        presets={presets}
        initialMinutes={Number(local[lateFor ?? 0]?.late_minutes) || presets[0] || 5}
        initialNote={local[lateFor ?? 0]?.note ?? ""}
      />

      <TeacherModal
        open={absentFor != null}
        onClose={() => setAbsentFor(null)}
        title="ثبت غیبت"
        footer={
          <div className="flex gap-2">
            <Button block onClick={confirmAbsent}>
              ثبت غیبت
            </Button>
            <Button variant="secondary" block onClick={() => setAbsentFor(null)}>
              انصراف
            </Button>
          </div>
        }
      >
        <Field label="دلیل غیبت (اختیاری)">
          <Input value={absentNote} onChange={(e) => setAbsentNote(e.target.value)} placeholder="مثلاً بیماری" />
        </Field>
      </TeacherModal>

      <TeacherModal
        open={earlyExitFor != null}
        onClose={() => setEarlyExitFor(null)}
        title="خروج زودتر از موعد"
        footer={
          <div className="flex gap-2">
            <Button block onClick={confirmEarlyExit}>
              ثبت خروج
            </Button>
            <Button variant="secondary" block onClick={() => setEarlyExitFor(null)}>
              انصراف
            </Button>
          </div>
        }
      >
        <Field label="توضیح (اختیاری)">
          <Input
            value={earlyExitNote}
            onChange={(e) => setEarlyExitNote(e.target.value)}
            placeholder="مثلاً مراجعه به دفتر یا بیماری"
          />
        </Field>
        <label className="mt-4 flex cursor-pointer items-start gap-2 rounded-2xl border border-slate-200 bg-slate-50 px-3 py-2.5 text-sm">
          <input
            type="checkbox"
            className="mt-0.5 h-4 w-4 rounded border-slate-300"
            checked={earlyExitJustified}
            onChange={(e) => setEarlyExitJustified(e.target.checked)}
          />
          <span>
            <span className="font-semibold text-slate-800">تاجیل موجه</span>
            <span className="mt-0.5 block text-xs text-slate-500">
              در موارد انضباطی لحاظ نمی‌شود.
            </span>
          </span>
        </label>
      </TeacherModal>

      <TeacherModal
        open={pastDateConfirmOpen}
        onClose={() => {
          pendingPastActionRef.current = null;
          setPastDateConfirmOpen(false);
        }}
        title="ثبت در روزی غیر از امروز"
        footer={
          <div className="flex gap-2">
            <Button block onClick={confirmPastDateEdit}>
              تأیید و ادامه
            </Button>
            <Button
              variant="secondary"
              block
              onClick={() => {
                pendingPastActionRef.current = null;
                setPastDateConfirmOpen(false);
              }}
            >
              انصراف
            </Button>
          </div>
        }
      >
        <p className="text-sm leading-6 text-slate-700">
          تاریخی که انتخاب کرده‌اید امروز نیست ({formatFaDate(date)}). ثبت یا ویرایش حضور و غیاب برای این روز انجام شود؟
        </p>
      </TeacherModal>

      <TeacherModal
        open={detailModal != null}
        onClose={() => setDetailModal(null)}
        title={detailModal?.title ?? "جزئیات"}
        footer={
          <Button variant="secondary" block onClick={() => setDetailModal(null)}>
            بستن
          </Button>
        }
      >
        {!detailModal?.items.length ? (
          <p className="text-sm text-slate-500">موردی ثبت نشده است.</p>
        ) : (
          <ul className="space-y-2">
            {detailModal.items.map((item, idx) => (
              <li key={`${item.name}-${idx}`} className="rounded-xl border border-slate-100 px-3 py-2.5 text-sm">
                <div className="flex flex-wrap items-center justify-between gap-2">
                  <span className="font-semibold text-slate-800">{item.name}</span>
                  <span className="text-xs font-medium text-slate-500">
                    {statusKindLabel(item.status)}
                    {item.minutes ? ` · ${item.minutes} دقیقه` : ""}
                    {item.justified ? " · موجه" : ""}
                  </span>
                </div>
                {item.note ? (
                  <p className="mt-1.5 text-sm leading-6 text-slate-600">{item.note}</p>
                ) : null}
              </li>
            ))}
          </ul>
        )}
      </TeacherModal>

      <StudentQuickModal
        studentProfileId={quickStudentId}
        classRoomId={classRoomId}
        subjectId={subjectId}
        date={date}
        onClose={() => setQuickStudentId(null)}
      />
    </div>
  );
}
