"use client";

import { useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import { Button, DatePicker, EmptyState, PageHeader, Select } from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatTime } from "@/lib/utils";
import { IconCheck, IconUsers } from "@/components/icons";
import { ATTENDANCE_STATUSES } from "@/lib/constants";

interface MinePair {
  classItemId: number | null;
  sectionItemId: number | null;
  subjectItemId: number | null;
  className: string | null;
  sectionName: string | null;
  subjectName: string | null;
}

interface AttEntry {
  studentId: number;
  roll: string;
  name: string;
  nameBn: string | null;
  photoUrl: string | null;
  status: string | null;
  inTime: string | null;
  outTime: string | null;
  source: string | null;
}

interface TakeSheet {
  date: string;
  mine: MinePair[];
  shifts: { id: number; name: string; nameBn: string }[];
  entries: AttEntry[];
  counts: { marked: number; present: number; absent: number; leave: number };
}

function todayISO(): string {
  return new Date().toISOString().slice(0, 10);
}

function Avatar({ name, photoUrl, size = 40 }: { name: string; photoUrl: string | null; size?: number }) {
  const initials = name.split(" ").map((w) => w[0]).slice(0, 2).join("").toUpperCase();
  return photoUrl ? (
    // eslint-disable-next-line @next/next/no-img-element
    <img src={photoUrl} alt={name} className="rounded-circle" style={{ width: size, height: size, objectFit: "cover" }} />
  ) : (
    <span
      className="rounded-circle d-inline-flex align-items-center justify-content-center f-w-700"
      style={{ width: size, height: size, background: "rgba(36,105,92,.12)", color: "#24695c", fontSize: size / 2.6 }}
    >
      {initials}
    </span>
  );
}

/** Teacher's attendance-taking panel — the same individual/bulk workflow the
    admin uses, scoped to the classes and subjects of the teacher's own
    teaching schedule. */
export default function MeAttendanceTakePage() {
  const { t, locale } = useLang();
  const [mode, setMode] = useState<"individual" | "bulk">("individual");
  const [date, setDate] = useState(todayISO());
  const [classId, setClassId] = useState("");
  const [sectionId, setSectionId] = useState("");
  const [shiftId, setShiftId] = useState("");
  const [subjectId, setSubjectId] = useState("");
  const [draft, setDraft] = useState<Record<number, string>>({});
  const [bulkPicked, setBulkPicked] = useState<Set<number>>(new Set());
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  const query = `/api/me/attendance/take?date=${date}` +
    (classId ? `&classItemId=${classId}` : "") +
    (sectionId ? `&sectionItemId=${sectionId}` : "") +
    (shiftId ? `&shiftItemId=${shiftId}` : "") +
    (subjectId ? `&subjectItemId=${subjectId}` : "");
  const sheet = useApi<TakeSheet>(query);

  const mine = sheet.data?.mine ?? [];
  const classes = useMemo(() => {
    const map = new Map<number, string>();
    for (const p of mine) if (p.classItemId) map.set(p.classItemId, p.className ?? "—");
    return [...map.entries()].map(([id, name]) => ({ id, name }));
  }, [mine]);
  const sections = useMemo(() => {
    const set = new Map<number, string>();
    for (const p of mine) {
      if (p.classItemId && String(p.classItemId) === classId && p.sectionItemId)
        set.set(p.sectionItemId, p.sectionName ?? "—");
    }
    return [...set.entries()].map(([id, name]) => ({ id, name }));
  }, [mine, classId]);
  const subjects = useMemo(() => {
    const set = new Map<number, string>();
    for (const p of mine) {
      if (p.classItemId && String(p.classItemId) === classId && p.subjectItemId)
        set.set(p.subjectItemId, p.subjectName ?? "—");
    }
    return [...set.entries()].map(([id, name]) => ({ id, name }));
  }, [mine, classId]);

  function resetEdits() {
    setDraft({});
    setBulkPicked(new Set());
  }

  function togglePick(id: number) {
    setBulkPicked((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  function applyBulkStatus(status: string) {
    if (bulkPicked.size === 0) return;
    const next = { ...draft };
    bulkPicked.forEach((id) => {
      next[id] = status;
    });
    setDraft(next);
  }

  const entries = sheet.data?.entries ?? [];
  const counts = sheet.data?.counts;

  async function save() {
    const list = Object.entries(draft).map(([studentId, status]) => ({
      studentId: Number(studentId),
      status,
    }));
    if (list.length === 0 || !classId) return;
    setSaving(true);
    setMessage(null);
    try {
      await api("/api/me/attendance/take", {
        method: "POST",
        body: JSON.stringify({
          date: sheet.data?.date ?? date,
          classItemId: Number(classId),
          sectionItemId: sectionId ? Number(sectionId) : null,
          shiftItemId: shiftId ? Number(shiftId) : null,
          subjectItemId: subjectId ? Number(subjectId) : null,
          entries: list,
        }),
      });
      resetEdits();
      setMessage({ type: "success", text: t.portal.studentsPage.attendanceSaved });
      sheet.reload();
    } catch (e) {
      const msg = e instanceof Error ? e.message : "";
      setMessage({
        type: "error",
        text: msg === "NOT_YOUR_CLASS" ? t.me.takeNotYourClass : t.common.tryAgain,
      });
    } finally {
      setSaving(false);
    }
  }

  return (
    <div>
      <PageHeader title={t.me.takeAttendanceTitle} subtitle={t.me.takeAttendanceSubtitle} />

      {message && (
        <div className="mb-4">
          <div className={`alert ${message.type === "success" ? "alert-success" : "alert-danger"} d-flex justify-content-between align-items-center`}>
            <span>{message.text}</span>
            <button type="button" className="btn-close" onClick={() => setMessage(null)} />
          </div>
        </div>
      )}

      <div className="card">
        <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
          <div className="d-flex flex-wrap align-items-center gap-2">
            <DatePicker
              wrapperClassName="form-group mb-0"
              style={{ maxWidth: 170 }}
              value={date}
              onChange={(e) => {
                setDate(e.target.value);
                resetEdits();
              }}
            />
            <div style={{ maxWidth: 170 }}>
              <Select
                wrapperClassName="form-group mb-0"
                value={classId}
                onChange={(e) => {
                  setClassId(e.target.value);
                  setSectionId("");
                  setSubjectId("");
                  resetEdits();
                }}
              >
                <option value="">{t.me.takePickClass}</option>
                {classes.map((c) => (
                  <option key={c.id} value={c.id}>{c.name}</option>
                ))}
              </Select>
            </div>
            <div style={{ maxWidth: 170 }}>
              <Select
                wrapperClassName="form-group mb-0"
                value={sectionId}
                onChange={(e) => {
                  setSectionId(e.target.value);
                  resetEdits();
                }}
              >
                <option value="">{t.portal.studentsPage.allSections}</option>
                {sections.map((c) => (
                  <option key={c.id} value={c.id}>{c.name}</option>
                ))}
              </Select>
            </div>
            <div style={{ maxWidth: 170 }}>
              <Select
                wrapperClassName="form-group mb-0"
                value={shiftId}
                onChange={(e) => {
                  setShiftId(e.target.value);
                  resetEdits();
                }}
              >
                <option value="">{t.portal.studentsPage.allShifts}</option>
                {(sheet.data?.shifts ?? []).map((c) => (
                  <option key={c.id} value={c.id}>
                    {locale === "bn" ? c.nameBn : c.name}
                  </option>
                ))}
              </Select>
            </div>
            <div style={{ maxWidth: 190 }}>
              <Select
                wrapperClassName="form-group mb-0"
                value={subjectId}
                onChange={(e) => {
                  setSubjectId(e.target.value);
                  resetEdits();
                }}
              >
                <option value="">{t.portal.studentsPage.subjectOptional}</option>
                {subjects.map((c) => (
                  <option key={c.id} value={c.id}>{c.name}</option>
                ))}
              </Select>
            </div>
            {counts && (
              <div className="d-flex flex-wrap gap-1">
                <span className="badge badge-success">{t.portal.dashboard.present}: {counts.present}</span>
                <span className="badge badge-danger">{t.portal.dashboard.absent}: {counts.absent}</span>
                <span className="badge badge-warning">{t.portal.dashboard.onLeave}: {counts.leave}</span>
              </div>
            )}
          </div>
          <div className="d-flex flex-wrap align-items-center gap-2">
            <div className="btn-group btn-group-sm" role="group" aria-label={t.portal.studentsPage.markingMode}>
              <button
                type="button"
                className={`btn ${mode === "individual" ? "btn-primary" : "btn-outline-secondary"}`}
                onClick={() => setMode("individual")}
              >
                {t.portal.studentsPage.modeIndividual}
              </button>
              <button
                type="button"
                className={`btn ${mode === "bulk" ? "btn-primary" : "btn-outline-secondary"}`}
                onClick={() => setMode("bulk")}
              >
                {t.portal.studentsPage.modeBulk}
              </button>
            </div>
            <Button onClick={save} loading={saving} disabled={Object.keys(draft).length === 0 || !classId}>
              <IconCheck className="svg-16" />
              <span className="ms-1">{t.portal.studentsPage.markAttendance}</span>
            </Button>
          </div>
        </div>
        <div className="card-body py-2">
          <p className="mb-0 ems-fs-11 text-muted">
            {mode === "individual"
              ? `${t.portal.studentsPage.attendanceHint} ${t.portal.studentsPage.subjectHint}`
              : `${t.portal.studentsPage.bulkHint} ${t.portal.studentsPage.subjectHint}`}
          </p>
        </div>
        {sheet.loading && !sheet.data ? (
          <div className="card-body text-center py-4">
            <span className="spinner-border text-primary" role="status" />
          </div>
        ) : !classId ? (
          <div className="card-body">
            <EmptyState icon={<IconUsers />} title={t.me.takePickClassFirst} />
          </div>
        ) : entries.length === 0 ? (
          <div className="card-body">
            <EmptyState icon={<IconUsers />} title={t.portal.studentsPage.noStudents} />
          </div>
        ) : mode === "individual" ? (
          <div className="table-responsive">
            <table className="table table-hover align-middle mb-0">
              <thead className="ems-table-head">
                <tr>
                  <th style={{ width: 60 }}>{t.portal.studentsPage.photoCol}</th>
                  <th>{t.portal.studentsPage.rollNo}</th>
                  <th>{t.common.name}</th>
                  <th className="text-end">{t.common.status}</th>
                </tr>
              </thead>
              <tbody>
                {entries.map((e) => {
                  const current = draft[e.studentId] ?? e.status;
                  return (
                    <tr key={e.studentId}>
                      <td>
                        <Avatar name={e.name} photoUrl={e.photoUrl} />
                      </td>
                      <td>
                        <span className="ems-roll-badge">{e.roll}</span>
                      </td>
                      <td>
                        <span className="f-w-600">
                          {e.name}
                          {e.nameBn && locale === "bn" && <span className="ms-1 ems-fs-11 text-muted f-w-500">({e.nameBn})</span>}
                        </span>
                        {e.source === "DEVICE" && e.inTime && (
                          <div className="ems-fs-11 text-muted mt-1">
                            <span className="badge badge-soft-teal me-1">{t.me.deviceBadge}</span>
                            {formatTime(e.inTime, locale)}
                            {e.outTime && e.outTime !== e.inTime ? ` → ${formatTime(e.outTime, locale)}` : ""}
                          </div>
                        )}
                      </td>
                      <td className="text-end">
                        <div className="btn-group btn-group-sm" role="group">
                          {ATTENDANCE_STATUSES.map((st) => (
                            <button
                              key={st}
                              type="button"
                              className={`btn ${
                                current === st
                                  ? st === "PRESENT"
                                    ? "btn-success"
                                    : st === "ABSENT"
                                      ? "btn-danger"
                                      : "btn-warning"
                                  : "btn-outline-secondary"
                              }`}
                              onClick={() => setDraft({ ...draft, [e.studentId]: st })}
                            >
                              {t.status[st as keyof typeof t.status]}
                            </button>
                          ))}
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        ) : (
          <>
            {/* Bulk toolbar — select students, then apply a status to all of them */}
            <div className="card-body py-2 border-bottom d-flex flex-wrap align-items-center gap-2">
              <span className="badge badge-primary">
                {bulkPicked.size} {t.portal.studentsPage.selectedLabel}
              </span>
              <span className="ems-fs-12 text-muted f-w-600">{t.portal.studentsPage.applyToSelected}</span>
              <div className="btn-group btn-group-sm" role="group">
                <button type="button" className="btn btn-success" disabled={bulkPicked.size === 0} onClick={() => applyBulkStatus("PRESENT")}>
                  {t.status.PRESENT}
                </button>
                <button type="button" className="btn btn-danger" disabled={bulkPicked.size === 0} onClick={() => applyBulkStatus("ABSENT")}>
                  {t.status.ABSENT}
                </button>
                <button type="button" className="btn btn-warning" disabled={bulkPicked.size === 0} onClick={() => applyBulkStatus("LEAVE")}>
                  {t.status.LEAVE}
                </button>
              </div>
              <button
                type="button"
                className="btn btn-sm btn-outline-secondary"
                disabled={bulkPicked.size === 0}
                onClick={() => setBulkPicked(new Set())}
              >
                {t.portal.studentsPage.clearSelection}
              </button>
              {Object.keys(draft).length > 0 && (
                <span className="ms-auto ems-fs-11 text-muted">
                  {Object.keys(draft).length} {t.portal.studentsPage.bulkApplied}
                </span>
              )}
            </div>
            <div className="table-responsive">
              <table className="table table-hover align-middle mb-0">
                <thead className="ems-table-head">
                  <tr>
                    <th style={{ width: 36 }}>
                      <input
                        type="checkbox"
                        className="form-check-input mt-0"
                        aria-label={t.portal.studentsPage.selectAll}
                        title={t.portal.studentsPage.selectAll}
                        checked={bulkPicked.size > 0 && bulkPicked.size === entries.length}
                        ref={(el) => {
                          if (el) el.indeterminate = bulkPicked.size > 0 && bulkPicked.size < entries.length;
                        }}
                        onChange={() =>
                          setBulkPicked(
                            bulkPicked.size === entries.length
                              ? new Set()
                              : new Set(entries.map((e) => e.studentId))
                          )
                        }
                      />
                    </th>
                    <th style={{ width: 60 }}>{t.portal.studentsPage.photoCol}</th>
                    <th>{t.portal.studentsPage.rollNo}</th>
                    <th>{t.common.name}</th>
                    <th className="text-end">{t.common.status}</th>
                  </tr>
                </thead>
                <tbody>
                  {entries.map((e) => {
                    const current = draft[e.studentId] ?? e.status;
                    const picked = bulkPicked.has(e.studentId);
                    return (
                      <tr key={e.studentId} className={picked ? "table-active" : ""}>
                        <td>
                          <input
                            type="checkbox"
                            className="form-check-input mt-0"
                            aria-label={e.name}
                            checked={picked}
                            onChange={() => togglePick(e.studentId)}
                          />
                        </td>
                        <td>
                          <Avatar name={e.name} photoUrl={e.photoUrl} />
                        </td>
                        <td>
                          <span className="ems-roll-badge">{e.roll}</span>
                        </td>
                        <td>
                          <span className="f-w-600">
                            {e.name}
                            {e.nameBn && locale === "bn" && <span className="ms-1 ems-fs-11 text-muted f-w-500">({e.nameBn})</span>}
                          </span>
                        </td>
                        <td className="text-end">
                          {current ? (
                            <span
                              className={`badge ${
                                current === "PRESENT" ? "badge-success" : current === "ABSENT" ? "badge-danger" : "badge-warning"
                              }`}
                            >
                              {t.status[current as keyof typeof t.status]}
                            </span>
                          ) : (
                            <span className="badge badge-light">{t.portal.studentsPage.unmarked}</span>
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          </>
        )}
      </div>
    </div>
  );
}
