"use client";

import { useMemo, useState } from "react";
import { useLang } from "@/context/LanguageContext";
import {
  Alert,
  Button,
  Card,
  DatePicker,
  EmptyState,
  Input,
  Modal,
  PageHeader,
  PageLoader,
  Pagination,
  Select,
  usePagination,
} from "@/components/ui";
import { api, useApi } from "@/lib/client";
import { formatDate } from "@/lib/utils";
import { BLOOD_GROUPS } from "@/lib/constants";
import { IconCard, IconEdit, IconShield, IconTrash, IconUsers } from "@/components/icons";
import { emsConfirm } from "@/components/ConfirmDialog";

interface StudentIdentity {
  id: number;
  roll: string;
  registrationNo: string | null;
  cardNo: string | null;
  rfidCardNo: string | null;
  cardIssuedAt: string | null;
  cardValidTill: string | null;
  bloodGroup: string | null;
  name: string;
  classItemId: number | null;
  classItem: { name: string; nameBn: string } | null;
  sectionItem: { name: string; nameBn: string } | null;
}

interface ClassOption {
  id: number;
  name: string;
  nameBn: string | null;
}

interface ManagerRow {
  staffId: number;
  staffName: string;
  employeeCode: string;
  designation: string;
  scope: number[] | null;
  createdAt: string;
}

interface StaffOption {
  id: number;
  name: string;
  employeeCode: string;
  designation: string;
  isManager: boolean;
}

interface IdentityData {
  access: "ADMIN" | "MANAGER" | "NONE";
  students: StudentIdentity[];
  classes: ClassOption[];
  managers?: ManagerRow[];
  staffOptions?: StaffOption[];
}

const emptyEdit = {
  roll: "",
  registrationNo: "",
  cardNo: "",
  rfidCardNo: "",
  bloodGroup: "",
  cardIssuedAt: "",
  cardValidTill: "",
};

export default function StudentIdentityPage() {
  const { t, locale } = useLang();
  const { data, loading, reload } = useApi<IdentityData>("/api/portal/identity");

  const [classFilter, setClassFilter] = useState("");
  const [query, setQuery] = useState("");

  // edit modal
  const [editStudent, setEditStudent] = useState<StudentIdentity | null>(null);
  const [edit, setEdit] = useState(emptyEdit);
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: "success" | "error"; text: string } | null>(null);

  // maintainer assignment form (admin)
  const [assignStaffId, setAssignStaffId] = useState("");
  const [assignAllClasses, setAssignAllClasses] = useState(true);
  const [assignClassIds, setAssignClassIds] = useState<number[]>([]);
  const [assigning, setAssigning] = useState(false);

  const isAdmin = data?.access === "ADMIN";
  const className = (c: ClassOption) => (locale === "bn" && c.nameBn ? c.nameBn : c.name);

  const students = useMemo(() => {
    const list = data?.students ?? [];
    const q = query.trim().toLowerCase();
    return list.filter((s) => {
      if (classFilter && s.classItemId !== Number(classFilter)) return false;
      if (!q) return true;
      return (
        s.roll.toLowerCase().includes(q) ||
        s.name.toLowerCase().includes(q) ||
        (s.registrationNo ?? "").toLowerCase().includes(q) ||
        (s.cardNo ?? "").toLowerCase().includes(q)
      );
    });
  }, [data, classFilter, query]);
  const pager = usePagination(students, 10);

  const availableStaff = (data?.staffOptions ?? []).filter((s) => !s.isManager);
  const managers = data?.managers ?? [];

  function scopeLabel(m: ManagerRow) {
    if (m.scope == null) return t.portal.identityPage.allClassesScope;
    const names = m.scope
      .map((id) => data?.classes.find((c) => c.id === id))
      .filter(Boolean)
      .map((c) => className(c!));
    return names.length ? names.join(", ") : t.portal.identityPage.allClassesScope;
  }

  function openEdit(s: StudentIdentity) {
    setEditStudent(s);
    setEdit({
      roll: s.roll,
      registrationNo: s.registrationNo ?? "",
      cardNo: s.cardNo ?? "",
      rfidCardNo: s.rfidCardNo ?? "",
      bloodGroup: s.bloodGroup ?? "",
      cardIssuedAt: s.cardIssuedAt ? s.cardIssuedAt.slice(0, 10) : "",
      cardValidTill: s.cardValidTill ? s.cardValidTill.slice(0, 10) : "",
    });
  }

  async function saveEdit(e: React.FormEvent) {
    e.preventDefault();
    if (!editStudent) return;
    setSaving(true);
    setMessage(null);
    try {
      await api(`/api/portal/identity/${editStudent.id}`, {
        method: "PATCH",
        body: JSON.stringify({
          roll: edit.roll,
          registrationNo: edit.registrationNo,
          cardNo: edit.cardNo,
          rfidCardNo: edit.rfidCardNo,
          bloodGroup: edit.bloodGroup,
          cardIssuedAt: edit.cardIssuedAt || "",
          cardValidTill: edit.cardValidTill || "",
        }),
      });
      setMessage({ type: "success", text: t.portal.identityPage.updated });
      setEditStudent(null);
      reload();
    } catch (err) {
      const code = err instanceof Error ? err.message : "";
      const text =
        code === "ROLL_EXISTS"
          ? t.portal.identityPage.rollExists
          : code === "REGISTRATION_EXISTS"
            ? t.portal.identityPage.registrationExists
            : code === "ROLL_REQUIRED"
              ? t.portal.identityPage.rollRequired
              : t.common.tryAgain;
      setMessage({ type: "error", text });
    } finally {
      setSaving(false);
    }
  }

  async function assignManager(e: React.FormEvent) {
    e.preventDefault();
    if (!assignStaffId) return;
    setAssigning(true);
    setMessage(null);
    try {
      await api("/api/portal/identity/managers", {
        method: "POST",
        body: JSON.stringify({
          staffId: Number(assignStaffId),
          classIds: assignAllClasses ? [] : assignClassIds,
        }),
      });
      setMessage({ type: "success", text: t.portal.identityPage.assigned });
      setAssignStaffId("");
      setAssignAllClasses(true);
      setAssignClassIds([]);
      reload();
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    } finally {
      setAssigning(false);
    }
  }

  async function removeManager(m: ManagerRow) {
    if (
      !(await emsConfirm({
        message: `${t.portal.identityPage.removeConfirm} ${m.staffName}?`,
        danger: true,
      }))
    )
      return;
    try {
      await api(`/api/portal/identity/managers/${m.staffId}`, { method: "DELETE" });
      setMessage({ type: "success", text: t.portal.identityPage.removed });
      reload();
    } catch {
      setMessage({ type: "error", text: t.common.tryAgain });
    }
  }

  if (loading) return <PageLoader text={t.common.loading} />;

  if (data?.access === "NONE") {
    return (
      <div>
        <PageHeader title={t.portal.identityPage.title} subtitle={t.portal.identityPage.subtitle} />
        <div className="card">
          <EmptyState icon={<IconShield />} title={t.portal.identityPage.noAccess} subtitle={t.portal.identityPage.noAccessHint} />
        </div>
      </div>
    );
  }

  return (
    <div>
      <PageHeader title={t.portal.identityPage.title} subtitle={t.portal.identityPage.subtitle} />

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

      {/* Maintainer assignments — admins decide who can maintain identity data */}
      {isAdmin && (
        <div className="ems-fade-in">
          <Card title={t.portal.identityPage.maintainersTitle} icon={<IconShield className="svg-20" />}>
            <p className="ems-fs-12 text-muted mb-3">{t.portal.identityPage.maintainersHint}</p>

            {managers.length > 0 && (
              <div className="table-responsive mb-4">
                <table className="table table-hover align-middle mb-0">
                  <thead className="ems-table-head">
                    <tr>
                      <th>{t.common.name}</th>
                      <th>{t.common.employee}</th>
                      <th>{t.common.designation}</th>
                      <th>{t.portal.identityPage.scopeLabel}</th>
                      <th className="text-end">{t.common.actions}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {managers.map((m) => (
                      <tr key={m.staffId}>
                        <td className="f-w-600">{m.staffName}</td>
                        <td>
                          <span className="badge badge-secondary">{m.employeeCode}</span>
                        </td>
                        <td className="ems-fs-13">
                          {t.designations[m.designation as keyof typeof t.designations] ?? m.designation}
                        </td>
                        <td className="ems-fs-13">{scopeLabel(m)}</td>
                        <td className="text-end">
                          <Button size="sm" variant="danger" onClick={() => removeManager(m)}>
                            <IconTrash className="svg-16" />
                            <span className="ms-1">{t.common.delete}</span>
                          </Button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}

            <form onSubmit={assignManager}>
              <div className="row g-3 align-items-end">
                <div className="col-md-4">
                  <Select
                    label={t.portal.identityPage.selectStaff}
                    value={assignStaffId}
                    onChange={(e) => setAssignStaffId(e.target.value)}
                    wrapperClassName="form-group mb-0"
                  >
                    <option value="">{t.common.select}</option>
                    {availableStaff.map((s) => (
                      <option key={s.id} value={s.id}>
                        {s.name} ({s.employeeCode})
                      </option>
                    ))}
                  </Select>
                </div>
                <div className="col-md-8">
                  <label className="col-form-label pt-0 f-w-600 d-block">{t.portal.identityPage.scopeLabel}</label>
                  <div className="form-check mb-2">
                    <input
                      id="scope-all"
                      type="checkbox"
                      className="form-check-input"
                      checked={assignAllClasses}
                      onChange={(e) => setAssignAllClasses(e.target.checked)}
                    />
                    <label htmlFor="scope-all" className="form-check-label ems-fs-13">
                      {t.portal.identityPage.allClassesScope}
                    </label>
                  </div>
                  {!assignAllClasses && (
                    <div className="d-flex flex-wrap gap-3">
                      {(data?.classes ?? []).map((c) => (
                        <div className="form-check" key={c.id}>
                          <input
                            id={`scope-class-${c.id}`}
                            type="checkbox"
                            className="form-check-input"
                            checked={assignClassIds.includes(c.id)}
                            onChange={(e) =>
                              setAssignClassIds((prev) =>
                                e.target.checked ? [...prev, c.id] : prev.filter((id) => id !== c.id)
                              )
                            }
                          />
                          <label htmlFor={`scope-class-${c.id}`} className="form-check-label ems-fs-13">
                            {className(c)}
                          </label>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              </div>
              <div className="d-flex justify-content-end mt-3">
                <Button type="submit" disabled={!assignStaffId || (!assignAllClasses && assignClassIds.length === 0)} loading={assigning}>
                  <IconShield className="svg-16" />
                  <span className="ms-1">{t.portal.identityPage.assign}</span>
                </Button>
              </div>
            </form>
          </Card>
        </div>
      )}

      {/* Students — roll / registration / card data */}
      <div className={isAdmin ? "mt-4 ems-fade-in" : "ems-fade-in"}>
        <Card title={t.portal.identityPage.studentsTitle} icon={<IconUsers className="svg-20" />}>
          <p className="ems-fs-12 text-muted mb-3">
            {data?.access === "MANAGER" ? t.portal.identityPage.studentsHintManager : t.portal.identityPage.studentsHint}
          </p>

          {students.length === 0 ? (
            <EmptyState icon={<IconCard />} title={t.portal.identityPage.noStudents} />
          ) : (
            <>
              <div className="row g-3 mb-3">
                <div className="col-md-5">
                  <Select
                    label={t.common.filter}
                    value={classFilter}
                    onChange={(e) => setClassFilter(e.target.value)}
                    wrapperClassName="form-group mb-0"
                  >
                    <option value="">{t.portal.identityPage.allClassesScope}</option>
                    {(data?.classes ?? []).map((c) => (
                      <option key={c.id} value={c.id}>
                        {className(c)}
                      </option>
                    ))}
                  </Select>
                </div>
                <div className="col-md-7">
                  <div className="form-group mb-0">
                    <label className="col-form-label pt-0 f-w-600">{t.common.search}</label>
                    <input
                      className="form-control"
                      value={query}
                      onChange={(e) => setQuery(e.target.value)}
                      placeholder={t.portal.identityPage.searchPlaceholder}
                    />
                  </div>
                </div>
              </div>

              <div className="table-responsive">
                <table className="table table-hover align-middle mb-0">
                  <thead className="ems-table-head">
                    <tr>
                      <th>{t.portal.identityPage.roll}</th>
                      <th>{t.common.name}</th>
                      <th>{t.portal.studentsPage.classLabel}</th>
                      <th>{t.portal.identityPage.registrationNo}</th>
                      <th>{t.portal.identityPage.cardNo}</th>
                      <th>{t.portal.identityPage.rfidCardNo}</th>
                      <th className="text-center">{t.portal.identityPage.bloodGroup}</th>
                      <th>{t.portal.identityPage.cardValidTill}</th>
                      <th className="text-end">{t.common.actions}</th>
                    </tr>
                  </thead>
                  <tbody>
                    {pager.paged.map((s) => (
                      <tr key={s.id}>
                        <td>
                          <span className="ems-roll-badge">{s.roll}</span>
                        </td>
                        <td className="f-w-600 ems-fs-13">{s.name}</td>
                        <td className="ems-fs-13">
                          {locale === "bn" && s.classItem?.nameBn ? s.classItem.nameBn : s.classItem?.name ?? "—"}
                          {s.sectionItem ? ` · ${locale === "bn" && s.sectionItem.nameBn ? s.sectionItem.nameBn : s.sectionItem.name}` : ""}
                        </td>
                        <td className="ems-fs-13">{s.registrationNo ?? <span className="text-muted">—</span>}</td>
                        <td className="ems-fs-13">{s.cardNo ?? <span className="text-muted">—</span>}</td>
                        <td className="ems-fs-13">{s.rfidCardNo ?? <span className="text-muted">—</span>}</td>
                        <td className="text-center ems-fs-13">{s.bloodGroup ?? <span className="text-muted">—</span>}</td>
                        <td className="ems-fs-13">
                          {s.cardValidTill ? formatDate(s.cardValidTill, locale) : <span className="text-muted">—</span>}
                        </td>
                        <td className="text-end">
                          <Button size="sm" variant="secondary" onClick={() => openEdit(s)}>
                            <IconEdit className="svg-16" />
                            <span className="ms-1">{t.common.edit}</span>
                          </Button>
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="mt-3">
                <Pagination
                  page={pager.page}
                  pageCount={pager.pageCount}
                  total={pager.total}
                  from={pager.from}
                  to={pager.to}
                  size={pager.size}
                  onPageChange={pager.setPage}
                  onSizeChange={pager.setSize}
                />
              </div>
            </>
          )}
        </Card>
      </div>

      {/* Identity edit modal */}
      <Modal
        open={!!editStudent}
        onClose={() => setEditStudent(null)}
        title={`${t.portal.identityPage.editTitle} — ${editStudent?.name ?? ""}`}
      >
        {editStudent && (
          <form onSubmit={saveEdit}>
            <div className="row g-3">
              <div className="col-md-6">
                <Input
                  label={`${t.portal.identityPage.roll} *`}
                  value={edit.roll}
                  onChange={(e) => setEdit({ ...edit, roll: e.target.value })}
                  required
                />
              </div>
              <div className="col-md-6">
                <Input
                  label={t.portal.identityPage.registrationNo}
                  value={edit.registrationNo}
                  onChange={(e) => setEdit({ ...edit, registrationNo: e.target.value })}
                />
              </div>
              <div className="col-md-6">
                <Input
                  label={t.portal.identityPage.cardNo}
                  value={edit.cardNo}
                  onChange={(e) => setEdit({ ...edit, cardNo: e.target.value })}
                />
              </div>
              <div className="col-md-6">
                <Input
                  label={t.portal.identityPage.rfidCardNo}
                  value={edit.rfidCardNo}
                  placeholder="0001234567"
                  onChange={(e) => setEdit({ ...edit, rfidCardNo: e.target.value })}
                />
              </div>
              <div className="col-md-6">
                <Select
                  label={t.portal.identityPage.bloodGroup}
                  value={edit.bloodGroup}
                  onChange={(e) => setEdit({ ...edit, bloodGroup: e.target.value })}
                  wrapperClassName="form-group mb-0"
                >
                  <option value="">{t.common.unassigned}</option>
                  {BLOOD_GROUPS.map((b) => (
                    <option key={b} value={b}>
                      {b}
                    </option>
                  ))}
                </Select>
              </div>
              <div className="col-md-6">
                <DatePicker
                  label={t.portal.identityPage.cardIssuedAt}
                  value={edit.cardIssuedAt}
                  onChange={(e) => setEdit({ ...edit, cardIssuedAt: e.target.value })}
                />
              </div>
              <div className="col-md-6">
                <DatePicker
                  label={t.portal.identityPage.cardValidTill}
                  value={edit.cardValidTill}
                  onChange={(e) => setEdit({ ...edit, cardValidTill: e.target.value })}
                />
              </div>
            </div>
            <div className="d-flex justify-content-end gap-2 pt-4">
              <Button type="button" variant="secondary" onClick={() => setEditStudent(null)}>
                {t.common.cancel}
              </Button>
              <Button type="submit" loading={saving}>
                {t.common.save}
              </Button>
            </div>
          </form>
        )}
      </Modal>
    </div>
  );
}
