"use client";

import Image from "next/image";
import { useEffect, useMemo, useRef, useState, type FormEvent } from "react";
import type { AttendanceSession, RecurringAttendanceSchedule } from "@/lib/attendance";
import type { MemberPass } from "@/lib/passes";
import { AdminAttendanceSchedule } from "@/components/admin-attendance-schedule";
import { csrfFetch } from "@/lib/client-csrf";

const weekdays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];

type DayClass = {
  key: string;
  title: string;
  startTime: string;
  instructor: string;
  session: AttendanceSession | null;
};

function todayInDelhi() {
  return new Intl.DateTimeFormat("en-CA", { timeZone: "Asia/Kolkata" }).format(new Date());
}

function weekdayForDate(isoDate: string) {
  const match = isoDate.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!match) return "";
  const date = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
  return weekdays[date.getUTCDay()] ?? "";
}

function dateLabel(isoDate: string) {
  const match = isoDate.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!match) return isoDate;
  const date = new Date(Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3])));
  return new Intl.DateTimeFormat("en-IN", {
    weekday: "long",
    day: "numeric",
    month: "short",
    year: "numeric",
    timeZone: "UTC",
  }).format(date);
}

function classKey(title: string, startTime: string) {
  return `${title}\u0000${startTime}`;
}

function windowState(sessionDate: string, startTime: string, active: boolean, opensAt?: string, closesAt?: string, now = new Date()) {
  if (!active) return "inactive" as const;
  const opens = opensAt ? new Date(opensAt).getTime() : new Date(`${sessionDate}T${startTime}:00+05:30`).getTime() - 12 * 60 * 60_000;
  const closes = closesAt ? new Date(closesAt).getTime() : new Date(`${sessionDate}T${startTime}:00+05:30`).getTime() + 12 * 60 * 60_000;
  if (Number.isNaN(opens) || Number.isNaN(closes)) return "inactive" as const;
  if (now.getTime() < opens) return "early" as const;
  if (now.getTime() > closes) return "closed" as const;
  return "open" as const;
}

function classesForDate(date: string, schedules: RecurringAttendanceSchedule[], sessions: AttendanceSession[]) {
  const weekday = weekdayForDate(date);
  const rows = new Map<string, DayClass>();
  for (const schedule of schedules) {
    if (!schedule.active || schedule.day !== weekday) continue;
    const key = classKey(schedule.title, schedule.startTime);
    rows.set(key, { key, title: schedule.title, startTime: schedule.startTime, instructor: schedule.instructor, session: null });
  }
  for (const session of sessions) {
    if (session.sessionDate !== date) continue;
    const key = classKey(session.title, session.startTime);
    const existing = rows.get(key);
    if (existing) existing.session = session;
    else rows.set(key, { key, title: session.title, startTime: session.startTime, instructor: session.instructor, session });
  }
  return [...rows.values()].sort((left, right) => left.startTime.localeCompare(right.startTime) || left.title.localeCompare(right.title));
}

type AttendedClass = {
  id: string;
  className: string;
  sessionDate: string;
  startTime: string;
  checkedInAt: string;
  source: "qr" | "manager";
};

function memberMatches(pass: MemberPass, query: string) {
  const text = query.trim().toLowerCase();
  if (text.length < 2) return false;
  const digits = text.replace(/\D/g, "");
  const phone = pass.phone.replace(/\D/g, "");
  return (
    pass.memberName.toLowerCase().includes(text) ||
    pass.email.toLowerCase().includes(text) ||
    pass.packageName.toLowerCase().includes(text) ||
    (digits.length >= 4 && phone.includes(digits))
  );
}

function MemberAttendanceSearch() {
  const [query, setQuery] = useState("");
  const [passes, setPasses] = useState<MemberPass[]>([]);
  const [selectedId, setSelectedId] = useState("");
  const [visits, setVisits] = useState<AttendedClass[] | null>(null);
  const [period, setPeriod] = useState("");

  useEffect(() => {
    let active = true;
    void fetch("/api/passes", { cache: "no-store" })
      .then(async (response) => {
        const data = (await response.json().catch(() => ({}))) as { passes?: MemberPass[] };
        if (active && response.ok) setPasses(data.passes ?? []);
      })
      .catch(() => undefined);
    return () => {
      active = false;
    };
  }, []);

  const matches = useMemo(() => passes.filter((pass) => memberMatches(pass, query)).slice(0, 8), [passes, query]);
  const selected = matches.find((pass) => pass.id === selectedId) ?? (matches.length === 1 ? matches[0] : null);
  const selectedPassId = selected?.id ?? "";

  useEffect(() => {
    if (!selectedPassId) {
      setVisits(null);
      setPeriod("");
      return;
    }
    let active = true;
    setVisits(null);
    void fetch(`/api/passes/${selectedPassId}/attendance`, { cache: "no-store" })
      .then(async (response) => {
        const data = (await response.json().catch(() => null)) as { from?: string; to?: string; visits?: AttendedClass[] } | null;
        if (!active) return;
        setPeriod(data?.from && data?.to ? `${dateLabel(data.from)} – ${dateLabel(data.to)}` : "");
        setVisits(data?.visits ?? []);
      })
      .catch(() => {
        if (active) setVisits([]);
      });
    return () => {
      active = false;
    };
  }, [selectedPassId]);

  return (
    <section className="rounded-2xl border border-[#d9cfbf] bg-[#faf7f2] p-5">
      <h2 className="text-xl font-semibold">Member attendance</h2>
      <p className="mt-2 text-sm leading-6 text-[#5c5248]">Search by name, phone, or email to see that member’s plan and the classes they attended.</p>
      <label className="mt-4 block text-sm font-semibold">
        Search member
        <input
          value={query}
          onChange={(event) => {
            setQuery(event.target.value);
            setSelectedId("");
          }}
          placeholder="Name, phone, or email"
          className="mt-1 min-h-11 w-full rounded-xl border border-[#d7cbb9] bg-white px-3 text-[14px] text-[#1a2228]"
        />
      </label>
      {query.trim().length >= 2 && matches.length > 1 ? (
        <div className="mt-3 flex flex-wrap gap-2">
          {matches.map((pass) => (
            <button
              key={pass.id}
              type="button"
              onClick={() => setSelectedId(pass.id)}
              className={`rounded-full px-3 py-1.5 text-sm font-semibold ${selected?.id === pass.id ? "bg-[#1a2228] text-white" : "bg-white text-[#1a2228] ring-1 ring-[#d7cbb9]"}`}
            >
              {pass.memberName} · {pass.packageName}
            </button>
          ))}
        </div>
      ) : null}
      {query.trim().length >= 2 && matches.length === 0 ? <p className="mt-3 text-sm text-[#5c5248]">No member matches that search.</p> : null}
      {selected ? (
        <div className="mt-4 rounded-2xl border border-[#e4d9cb] bg-white p-4">
          <p className="text-lg font-semibold">{selected.memberName}</p>
          <p className="mt-1 text-sm text-[#5c5248]">{selected.phone} · {selected.email}</p>
          <dl className="mt-3 grid gap-2 text-sm sm:grid-cols-4">
            <div><dt className="text-xs font-bold uppercase tracking-wide text-[#71675d]">Plan</dt><dd>{selected.packageName}</dd></div>
            <div><dt className="text-xs font-bold uppercase tracking-wide text-[#71675d]">Classes left</dt><dd>{selected.remainingCredits} of {selected.totalCredits}</dd></div>
            <div><dt className="text-xs font-bold uppercase tracking-wide text-[#71675d]">Expires</dt><dd>{dateLabel(selected.expiresAt)}</dd></div>
            <div><dt className="text-xs font-bold uppercase tracking-wide text-[#71675d]">Status</dt><dd className="capitalize">{selected.status}</dd></div>
          </dl>
          <p className="mt-4 text-sm font-semibold">Classes attended{period ? ` · ${period}` : ""}</p>
          {visits === null ? (
            <p className="mt-2 text-sm text-[#5c5248]">Loading attended classes…</p>
          ) : visits.length === 0 ? (
            <p className="mt-2 text-sm text-[#5c5248]">No check-ins in this membership yet.</p>
          ) : (
            <ul className="mt-2 divide-y divide-[#e4d9cb]">
              {visits.map((visit) => (
                <li key={visit.id} className="flex flex-wrap items-baseline justify-between gap-2 py-2 text-sm">
                  <span>
                    <span className="font-semibold">{visit.className}</span>
                    <span className="mt-0.5 block text-[#5c5248]">{dateLabel(visit.sessionDate)} at {visit.startTime}</span>
                  </span>
                  <span className="text-[#71675d]">
                    Checked in {new Date(visit.checkedInAt).toLocaleString("en-IN", { timeZone: "Asia/Kolkata", day: "numeric", month: "short", hour: "numeric", minute: "2-digit" })}
                    {" · "}
                    {visit.source === "manager" ? "Manager" : "QR"}
                  </span>
                </li>
              ))}
            </ul>
          )}
        </div>
      ) : null}
    </section>
  );
}

function defaultOpenKey(date: string, classes: DayClass[]) {
  const withRecords = classes.find((item) => (item.session?.records.length ?? 0) > 0);
  if (withRecords) return withRecords.key;
  const openNow = classes.find((item) => {
    const session = item.session;
    return windowState(date, item.startTime, session ? session.active : true, session?.opensAt, session?.closesAt) === "open";
  });
  return openNow?.key || classes[0]?.key || "";
}

function statusLabel(state: ReturnType<typeof windowState>, hasSession: boolean) {
  if (!hasSession) return "Scheduled";
  if (state === "inactive") return "Closed";
  if (state === "open") return "Check-in open";
  if (state === "early") return "Upcoming";
  return "Finished";
}

export function AdminAttendance() {
  const [sessions, setSessions] = useState<AttendanceSession[]>([]);
  const [schedules, setSchedules] = useState<RecurringAttendanceSchedule[]>([]);
  const [overrideScheduleId, setOverrideScheduleId] = useState("");
  const [overrideDate, setOverrideDate] = useState(todayInDelhi());
  const [memberName, setMemberName] = useState("");
  const [memberEmail, setMemberEmail] = useState("");
  const [notes, setNotes] = useState("");
  const [manualName, setManualName] = useState("");
  const [manualContact, setManualContact] = useState("");
  const [notice, setNotice] = useState("");
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [historyDate, setHistoryDate] = useState(todayInDelhi);
  const [selectedClassKey, setSelectedClassKey] = useState("");
  const historyDateRef = useRef(historyDate);
  historyDateRef.current = historyDate;

  async function load(date = historyDateRef.current) {
    const [sessionsResponse, schedulesResponse] = await Promise.all([
      fetch(`/api/admin/attendance/sessions?date=${encodeURIComponent(date)}`, { cache: "no-store" }),
      fetch("/api/admin/attendance/schedule", { cache: "no-store" }),
    ]);
    const sessionsData = (await sessionsResponse.json()) as { sessions?: AttendanceSession[] };
    const schedulesData = (await schedulesResponse.json()) as { schedules?: RecurringAttendanceSchedule[] };
    setSessions(sessionsData.sessions ?? []);
    setSchedules(schedulesData.schedules ?? []);
    setOverrideScheduleId((current) => current || schedulesData.schedules?.[0]?.id || "");
    setLoading(false);
  }

  useEffect(() => {
    let active = true;
    async function loadForDate() {
      const [sessionsResponse, schedulesResponse] = await Promise.all([
        fetch(`/api/admin/attendance/sessions?date=${encodeURIComponent(historyDate)}`, { cache: "no-store" }),
        fetch("/api/admin/attendance/schedule", { cache: "no-store" }),
      ]);
      const sessionsData = (await sessionsResponse.json()) as { sessions?: AttendanceSession[] };
      const schedulesData = (await schedulesResponse.json()) as { schedules?: RecurringAttendanceSchedule[] };
      if (!active) return;
      setSessions(sessionsData.sessions ?? []);
      setSchedules(schedulesData.schedules ?? []);
      setOverrideScheduleId((current) => current || schedulesData.schedules?.[0]?.id || "");
      setLoading(false);
    }
    void loadForDate();
    return () => {
      active = false;
    };
  }, [historyDate]);

  async function sessionAction(id: string, action: "rotate" | "open" | "close") {
    setSaving(true);
    const response = await csrfFetch("/api/admin/attendance/sessions", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ id, action }),
    });
    setNotice(response.ok ? `Attendance session ${action === "rotate" ? "QR rotated" : `${action}ed`}.` : "Could not update session.");
    await load();
    setSaving(false);
  }

  async function createQrTestSession() {
    setSaving(true);
    setNotice("");
    const response = await csrfFetch("/api/admin/attendance/sessions", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ testSession: true }),
    });
    const data = (await response.json().catch(() => ({}))) as {
      session?: AttendanceSession;
      error?: string;
    };
    setNotice(
      response.ok && data.session
        ? `QR test class is open now: ${data.session.sessionDate} at ${data.session.startTime}.`
        : data.error || "Could not create QR test class.",
    );
    await load();
    setSaving(false);
  }

  async function addOverride(event: FormEvent) {
    event.preventDefault();
    const schedule = schedules.find((item) => item.id === overrideScheduleId);
    if (!schedule) {
      setNotice("Select a recurring session.");
      return;
    }
    setSaving(true);
    setNotice("");
    const sessionResponse = await csrfFetch("/api/admin/attendance/sessions", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        title: schedule.title,
        instructor: schedule.instructor,
        sessionDate: overrideDate,
        startTime: schedule.startTime,
      }),
    });
    const sessionData = (await sessionResponse.json().catch(() => ({}))) as {
      session?: AttendanceSession;
      error?: string;
    };
    if (!sessionResponse.ok || !sessionData.session) {
      setNotice(sessionData.error || "Could not prepare the attendance session.");
      setSaving(false);
      return;
    }

    const response = await csrfFetch("/api/admin/attendance/records", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ sessionId: sessionData.session.id, email: memberEmail, name: memberName, notes }),
    });
    const data = (await response.json().catch(() => ({}))) as { error?: string };
    setNotice(response.ok ? "Manual attendance recorded." : data.error || "Could not record attendance.");
    if (response.ok) {
      setMemberEmail("");
      setMemberName("");
      setNotes("");
    }
    await load();
    setSaving(false);
  }

  async function addAttendedMember(item: DayClass, event: FormEvent) {
    event.preventDefault();
    const contact = manualContact.trim();
    const email = contact.includes("@") ? contact : "";
    const phone = email ? "" : contact;
    if (!manualName.trim() || (!email && !phone)) {
      setNotice("Enter the member name and a phone or email.");
      return;
    }
    setSaving(true);
    setNotice("");
    const sessionResponse = await csrfFetch("/api/admin/attendance/sessions", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        title: item.title,
        instructor: item.instructor || item.session?.instructor || "Studio",
        sessionDate: historyDate,
        startTime: item.startTime,
      }),
    });
    const sessionData = (await sessionResponse.json().catch(() => ({}))) as { session?: AttendanceSession; error?: string };
    if (!sessionResponse.ok || !sessionData.session) {
      setNotice(sessionData.error || "Could not open this class for attendance.");
      setSaving(false);
      return;
    }
    const response = await csrfFetch("/api/admin/attendance/records", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        sessionId: sessionData.session.id,
        name: manualName.trim(),
        email,
        phone,
        notes: "Added by manager",
      }),
    });
    const data = (await response.json().catch(() => ({}))) as { error?: string };
    setNotice(response.ok ? `${manualName.trim()} is marked present for ${item.title}.` : data.error || "Could not add this member.");
    if (response.ok) {
      setManualName("");
      setManualContact("");
      setSelectedClassKey(item.key);
    }
    await load();
    setSaving(false);
  }

  async function removeRecord(id: string) {
    if (!window.confirm("Remove this attendance record?")) return;
    setSaving(true);
    const response = await csrfFetch(`/api/admin/attendance/records?id=${encodeURIComponent(id)}`, { method: "DELETE" });
    setNotice(response.ok ? "Attendance record removed." : "Could not remove attendance record.");
    await load();
    setSaving(false);
  }

  const dayClasses = useMemo(() => classesForDate(historyDate, schedules, sessions), [historyDate, schedules, sessions]);
  const openKey = dayClasses.some((item) => item.key === selectedClassKey) ? selectedClassKey : defaultOpenKey(historyDate, dayClasses);
  const fieldClass = "mt-1 min-h-11 w-full rounded-xl border border-[#d7cbb9] bg-white px-3 text-[14px] text-[#1a2228]";

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-semibold sm:text-3xl">Attendance</h1>
        <p className="mt-1 text-[15px] text-[#5c5248]">Use one permanent studio QR, manage class sessions, and correct attendance when needed.</p>
      </div>

      <MemberAttendanceSearch />

      <section className="rounded-2xl border border-[#c7b28f] bg-[#f5ecdd] p-5">
        <div className="flex flex-col gap-6 sm:flex-row sm:items-center">
          <div className="shrink-0 rounded-xl bg-white p-2 ring-1 ring-[#d7cbb9]">
            <Image
              src="/api/admin/attendance/studio-qr"
              alt="Permanent Zelosity studio attendance QR"
              width={200}
              height={200}
              unoptimized
              className="size-48"
            />
          </div>
          <div>
            <p className="text-xs font-bold uppercase tracking-[0.16em] text-[#9d7a52]">Recommended</p>
            <h2 className="mt-2 text-2xl font-semibold">One QR for every studio class</h2>
            <p className="mt-3 max-w-xl text-sm leading-6 text-[#5c5248]">
              Print this once and display it at reception. Members scan the same QR every day and choose from classes
              whose check-in window is currently open.
            </p>
            <a
              href="/api/admin/attendance/studio-qr"
              target="_blank"
              rel="noreferrer"
              className="mt-5 inline-flex min-h-11 items-center rounded-xl bg-[#1a2228] px-5 text-sm font-bold text-white"
            >
              Open / print studio QR
            </a>
            <button
              type="button"
              disabled={saving}
              onClick={() => void createQrTestSession()}
              className="mt-3 inline-flex min-h-11 items-center rounded-xl border border-[#c7b28f] px-5 text-sm font-bold text-[#1a2228] disabled:opacity-50 sm:ml-3 sm:mt-5"
            >
              Create QR test class
            </button>
            <p className="mt-3 text-xs leading-5 text-[#71675d]">
              Local testing helper: sign in with WhatsApp +91 99999 99999 after creating the test class. The local
              verification code is shown on screen.
            </p>
          </div>
        </div>
      </section>

      <AdminAttendanceSchedule />

      <form onSubmit={addOverride} className="rounded-2xl border border-[#d9cfbf] bg-[#faf7f2] p-5">
        <h2 className="text-xl font-semibold">Manager override</h2>
        <p className="mt-2 text-sm leading-6 text-[#5c5248]">Use this only when a member cannot complete self check-in.</p>
        <div className="mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-5">
          <label className="text-sm font-semibold">Session<select value={overrideScheduleId} onChange={(event) => setOverrideScheduleId(event.target.value)} className={fieldClass} required>
            <option value="">Select class</option>
            {schedules.filter((schedule) => schedule.active).map((schedule) => <option key={schedule.id} value={schedule.id}>{schedule.day} · {schedule.startTime} · {schedule.title}</option>)}
          </select></label>
          <label className="text-sm font-semibold">Class date<input type="date" value={overrideDate} onChange={(event) => setOverrideDate(event.target.value)} className={fieldClass} required /></label>
          <label className="text-sm font-semibold">Member name<input value={memberName} onChange={(event) => setMemberName(event.target.value)} className={fieldClass} required /></label>
          <label className="text-sm font-semibold">Member email<input type="email" value={memberEmail} onChange={(event) => setMemberEmail(event.target.value)} className={fieldClass} required /></label>
          <label className="text-sm font-semibold">Reason / note<input value={notes} onChange={(event) => setNotes(event.target.value)} className={fieldClass} placeholder="Walk-in or device issue" /></label>
        </div>
        <button type="submit" disabled={saving || !overrideScheduleId} className="mt-4 min-h-11 rounded-xl bg-[#3f5e4f] px-5 text-sm font-bold text-white disabled:opacity-50">Record attendance</button>
      </form>

      {notice ? <p className="rounded-xl bg-[#e8dccb] px-4 py-3 text-sm font-semibold text-[#3d342c]">{notice}</p> : null}

      <section className="rounded-2xl border border-[#d9cfbf] bg-[#faf7f2] p-5">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between">
          <div>
            <h2 className="text-xl font-semibold">Class attendance</h2>
            <p className="mt-2 text-sm leading-6 text-[#5c5248]">{dateLabel(historyDate)}. Open a class to see who checked in, or to close and correct the record.</p>
          </div>
          <label className="text-sm font-semibold">
            Date
            <input
              type="date"
              value={historyDate}
              onChange={(event) => {
                setSelectedClassKey("");
                setHistoryDate(event.target.value || todayInDelhi());
              }}
              className={fieldClass}
            />
          </label>
        </div>
        {loading ? <p className="mt-4 text-sm text-[#5c5248]">Loading attendance…</p> : dayClasses.length === 0 ? <p className="mt-4 text-sm text-[#5c5248]">No classes on this date.</p> : (
          <div className="mt-4 grid gap-3">
            {dayClasses.map((item) => {
              const session = item.session;
              const expanded = item.key === openKey;
              const state = windowState(historyDate, item.startTime, session ? session.active : true, session?.opensAt, session?.closesAt);
              const label = statusLabel(state, Boolean(session));
              const checkedIn = session?.records.length ?? 0;
              return (
                <article key={item.key} className={`rounded-2xl border p-4 ${expanded ? "border-[#9d7a52] bg-white" : "border-[#e4d9cb] bg-[#faf7f2]"}`}>
                  <button
                    type="button"
                    aria-expanded={expanded}
                    onClick={() => setSelectedClassKey(item.key)}
                    className="flex w-full flex-wrap items-center justify-between gap-3 text-left"
                  >
                    <span>
                      <span className="text-xs font-bold uppercase tracking-[0.14em] text-[#9d7a52]">{item.startTime}</span>
                      <span className="mt-1 block text-lg font-semibold">{item.title}</span>
                    </span>
                    <span className="flex items-center gap-3">
                      <span className="text-sm font-semibold">{checkedIn} checked in</span>
                      <span className={`rounded-full px-2.5 py-1 text-xs font-bold ${label === "Closed" ? "bg-[#eee5e3] text-[#7a2e36]" : label === "Check-in open" ? "bg-[#e3eee7] text-[#274739]" : "bg-[#f3eee6] text-[#5c5248]"}`}>{label}</span>
                    </span>
                  </button>
                  {expanded ? (
                    <div className="mt-4 border-t border-[#e4d9cb] pt-4">
                      <p className="text-sm text-[#5c5248]">{item.title} · {dateLabel(historyDate)} · {item.startTime}</p>
                      {session ? (
                        <button
                          type="button"
                          disabled={saving}
                          onClick={() => void sessionAction(session.id, session.active ? "close" : "open")}
                          className="mt-3 rounded-lg bg-[#1a2228] px-3 py-2 text-xs font-bold text-white disabled:opacity-50"
                        >
                          {session.active ? "Close" : "Reopen"}
                        </button>
                      ) : (
                        <p className="mt-2 text-sm text-[#5c5248]">Check-in has not been opened for this class yet. Adding a member opens it.</p>
                      )}
                      <form onSubmit={(event) => void addAttendedMember(item, event)} className="mt-4 grid gap-3 sm:grid-cols-[1fr_1fr_auto] sm:items-end">
                        <label className="text-sm font-semibold">Member name
                          <input value={manualName} onChange={(event) => setManualName(event.target.value)} className={fieldClass} required />
                        </label>
                        <label className="text-sm font-semibold">Phone or email
                          <input value={manualContact} onChange={(event) => setManualContact(event.target.value)} className={fieldClass} required />
                        </label>
                        <button type="submit" disabled={saving} className="min-h-11 rounded-xl bg-[#3f5e4f] px-4 text-sm font-bold text-white disabled:opacity-50">Add attended member</button>
                      </form>
                      {session && session.records.length > 0 ? (
                        <div className="mt-4 overflow-x-auto">
                          <table className="w-full min-w-[40rem] text-left text-sm">
                            <thead className="text-xs uppercase tracking-wide text-[#71675d]">
                              <tr>
                                <th className="pb-2">Member</th>
                                <th className="pb-2">Class</th>
                                <th className="pb-2">Class time</th>
                                <th className="pb-2">Checked in</th>
                                <th className="pb-2">Source</th>
                                <th className="pb-2 text-right">Action</th>
                              </tr>
                            </thead>
                            <tbody>
                              {session.records.map((record) => (
                                <tr key={record.id} className="border-t border-[#e4d9cb]">
                                  <td className="py-3"><span className="font-semibold">{record.memberName}</span><span className="block text-xs text-[#71675d]">{record.memberPhone || record.memberEmail}</span></td>
                                  <td className="py-3">{item.title}<span className="block text-xs text-[#71675d]">{dateLabel(historyDate)}</span></td>
                                  <td className="py-3">{item.startTime}</td>
                                  <td className="py-3">{new Date(record.checkedInAt).toLocaleString("en-IN", { timeZone: "Asia/Kolkata", day: "numeric", month: "short", hour: "numeric", minute: "2-digit" })}</td>
                                  <td className="py-3">{record.source === "admin_override" ? "Manager" : "QR"}</td>
                                  <td className="py-3 text-right"><button type="button" onClick={() => void removeRecord(record.id)} className="text-xs font-bold text-[#7a2e36]">Remove</button></td>
                                </tr>
                              ))}
                            </tbody>
                          </table>
                        </div>
                      ) : (
                        <p className="mt-4 text-sm text-[#5c5248]">No one has checked in for this class.</p>
                      )}
                    </div>
                  ) : null}
                </article>
              );
            })}
          </div>
        )}
      </section>
    </div>
  );
}
