"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { ApiError } from "@/lib/api";
import {
  fetchAttendanceAlerts,
  fetchAttendanceClasses,
  fetchAttendanceStudents,
  type AlertRowsPayload,
  type ClassRowsPayload,
  type StudentRow,
  type StudentRowsPayload,
} from "@/lib/attendance-report";
import { CardTitle, GlassCard, MiniStat, fa } from "./AttendancePrimitives";
import {
  AlertsList,
  ChipGroup,
  ClassesTable,
  GroupSendButton,
  LIST_FILTER_OPTIONS,
  MessageModal,
  Pager,
  SMS_FILTER_OPTIONS,
  STUDENT_FILTER_OPTIONS,
  StudentDrawer,
  StudentsTable,
  type MessageRole,
  type MessageTarget,
} from "./AttendanceShared";
import { AttendanceFilterBar } from "./AttendanceFilterBar";
import { AttendanceExportMenu } from "./AttendanceExportMenu";
import { DASHBOARD_PATH, useAttendanceFilters, type RecordsDataset } from "./useAttendanceFilters";

const DATASET_OPTIONS: Array<[RecordsDataset, string]> = [
  ["students", "دانش‌آموزان"],
  ["classes", "لیست‌های معلمان"],
  ["alerts", "هشدارهای شعب"],
];

const PER_PAGE = 50;

export function AttendanceRecords() {
  const search = useSearchParams();
  const filters = useAttendanceFilters();
  const { state, patch, scopeQuery, scopeKey, branchLabel, dateLabel, optionsError } = filters;

  const [dataset, setDataset] = useState<RecordsDataset>(() => {
    const raw = search.get("dataset");
    return raw === "classes" || raw === "alerts" ? raw : "students";
  });
  const [page, setPage] = useState(1);
  const [students, setStudents] = useState<StudentRowsPayload | null>(null);
  const [classes, setClasses] = useState<ClassRowsPayload | null>(null);
  const [alerts, setAlerts] = useState<AlertRowsPayload | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  const [selectedStudent, setSelectedStudent] = useState<StudentRow | null>(null);
  const [messageTarget, setMessageTarget] = useState<MessageTarget | null>(null);
  const [exportOpen, setExportOpen] = useState(false);
  const [picking, setPicking] = useState(false);
  const [pickedRowIds, setPickedRowIds] = useState<string[]>([]);
  const [pickedAlertIds, setPickedAlertIds] = useState<number[]>([]);
  const [pickError, setPickError] = useState<string | null>(null);

  const rowQuery = useMemo(
    () => ({
      ...scopeQuery,
      status: state.status,
      lists: state.lists,
      sms: state.sms,
      q: state.q,
      page,
      perPage: PER_PAGE,
    }),
    [scopeQuery, state.status, state.lists, state.sms, state.q, page],
  );

  // صفحه با هر تغییر فیلتر به اول برمی‌گردد تا شمارش و ردیف‌ها هم‌خوان بمانند.
  useEffect(() => {
    setPage(1);
  }, [scopeKey, state.status, state.lists, state.sms, state.q, dataset]);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    const request =
      dataset === "students"
        ? fetchAttendanceStudents(rowQuery).then((data) => {
            if (!cancelled) setStudents(data);
          })
        : dataset === "classes"
          ? fetchAttendanceClasses(rowQuery).then((data) => {
              if (!cancelled) setClasses(data);
            })
          : fetchAttendanceAlerts({ ...scopeQuery, limit: 200 }).then((data) => {
              if (!cancelled) setAlerts(data);
            });

    request
      .then(() => {
        if (!cancelled) setError(null);
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setError(err instanceof ApiError ? err.message : "خطا در دریافت ریز داده‌ها");
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });

    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dataset, JSON.stringify(rowQuery)]);

  function resetPicking() {
    setPicking(false);
    setPickedRowIds([]);
    setPickedAlertIds([]);
    setPickError(null);
  }

  function toggleRow(id: string) {
    setPickError(null);
    setPickedRowIds((prev) => (prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]));
  }

  function sendToPicked() {
    let names: string[] = [];
    let role: MessageRole = "parent";

    if (dataset === "students") {
      names = (students?.rows ?? [])
        .filter((row) => pickedRowIds.includes(row.id))
        .map((row) => `ولی ${row.student_name}`);
    } else if (dataset === "classes") {
      role = "teacher";
      names = (classes?.rows ?? [])
        .filter((row) => pickedRowIds.includes(row.id))
        .map((row) => row.teacher_name);
    } else {
      role = "manager";
      names = (alerts?.rows ?? [])
        .filter((row) => pickedAlertIds.includes(row.id))
        .map((row) => `مدیر ${row.branch_name ?? "شعبه"}`);
    }

    if (names.length === 0) {
      setPickError("حداقل یک ردیف را از لیست انتخاب کنید.");
      return;
    }

    const unique = Array.from(new Set(names));
    resetPicking();
    setMessageTarget({
      name: `${fa(unique.length)} نفر`,
      role,
      hint: unique.join("، "),
    });
  }

  const rowCount =
    dataset === "students"
      ? (students?.total ?? 0)
      : dataset === "classes"
        ? (classes?.total ?? 0)
        : (alerts?.total ?? 0);

  const truncated = dataset === "students" && students?.truncated === true;
  const showDate = filters.range.from !== filters.range.to;
  const absenceCap = students?.filters.policy.absence_cap_days ?? 3;

  return (
    <div className="relative -mx-4 -mt-2 min-h-[70vh] bg-[radial-gradient(1200px_500px_at_100%_-10%,rgba(13,148,136,0.16),transparent),radial-gradient(900px_400px_at_0%_0%,rgba(14,165,233,0.12),transparent)] px-4 pb-10 pt-3 lg:-mx-6 lg:px-6">
      <header className="relative z-30 mb-4 rounded-[1.7rem] border border-white/80 bg-white/75 p-4 shadow-card backdrop-blur-md lg:p-5">
        <div className="flex flex-wrap items-start justify-between gap-3">
          <div>
            <p className="text-[11px] font-bold text-teal-700">ریز داده‌های حضور و غیاب</p>
            <h2 className="mt-0.5 text-lg font-black text-slate-900">فهرست تفصیلی اعداد گزارش</h2>
            <p className="mt-1 text-xs text-slate-500">
              {dateLabel} · محدوده: {branchLabel} · {fa(rowCount)} ردیف
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <div className="relative">
              <Button onClick={() => setExportOpen((open) => !open)}>
                ایجاد خروجی
                <span aria-hidden className="ms-2 text-[10px]">
                  ▾
                </span>
              </Button>
              {exportOpen ? (
                <AttendanceExportMenu
                  query={rowQuery}
                  scopeLabel={branchLabel}
                  dateLabel={dateLabel}
                  onClose={() => setExportOpen(false)}
                />
              ) : null}
            </div>
            <Link
              href={DASHBOARD_PATH}
              className="rounded-xl border border-slate-200 bg-white px-4 py-2 text-sm font-bold text-slate-700 transition hover:bg-slate-50"
            >
              بازگشت به داشبورد
            </Link>
          </div>
        </div>

        <div className="mt-4">
          <AttendanceFilterBar filters={filters} showSearch />
        </div>
      </header>

      {optionsError ? (
        <div className="mb-4">
          <Alert tone="warning">{optionsError}</Alert>
        </div>
      ) : null}
      {error ? (
        <div className="mb-4">
          <Alert tone="error">{error}</Alert>
        </div>
      ) : null}
      {truncated ? (
        <div className="mb-4">
          <Alert tone="warning">
            بازه انتخابی برای نمایش ریز داده‌ها بزرگ است. بازه یا فیلترها را محدودتر کنید تا ردیف‌ها
            محاسبه شود.
          </Alert>
        </div>
      ) : null}

      <div className="grid gap-4 xl:grid-cols-[minmax(0,1fr)_17rem]">
        <div className="space-y-4">
          <GlassCard>
            <CardTitle
              kicker="جدول داده"
              title={DATASET_OPTIONS.find(([key]) => key === dataset)?.[1] ?? "داده"}
              action={
                <GroupSendButton
                  picking={picking}
                  count={dataset === "alerts" ? pickedAlertIds.length : pickedRowIds.length}
                  onStart={() => {
                    setPicking(true);
                    setPickedRowIds([]);
                    setPickedAlertIds([]);
                    setPickError(null);
                  }}
                  onSend={sendToPicked}
                  onCancel={resetPicking}
                />
              }
            />

            <div className="mb-3 flex flex-wrap gap-2">
              {DATASET_OPTIONS.map(([key, label]) => (
                <button
                  key={key}
                  type="button"
                  onClick={() => {
                    setDataset(key);
                    resetPicking();
                  }}
                  className={`rounded-xl px-3 py-1.5 text-xs font-bold transition ${
                    dataset === key ? "bg-teal-700 text-white" : "bg-slate-100 text-slate-600"
                  }`}
                >
                  {label}
                </button>
              ))}
            </div>

            {dataset === "students" ? (
              <div className="mb-3 space-y-2">
                <ChipGroup
                  options={STUDENT_FILTER_OPTIONS}
                  value={state.status}
                  counts={students?.counts}
                  onChange={(status) => {
                    patch({ status });
                    resetPicking();
                  }}
                />
                <div className="flex flex-wrap items-center gap-2">
                  <span className="text-[11px] font-bold text-slate-400">وضعیت پیامک</span>
                  <ChipGroup
                    options={SMS_FILTER_OPTIONS}
                    value={state.sms}
                    onChange={(sms) => {
                      patch({ sms });
                      resetPicking();
                    }}
                  />
                </div>
              </div>
            ) : null}

            {dataset === "classes" ? (
              <div className="mb-3">
                <ChipGroup
                  options={LIST_FILTER_OPTIONS}
                  value={state.lists}
                  counts={classes?.counts}
                  onChange={(lists) => {
                    patch({ lists });
                    resetPicking();
                  }}
                />
              </div>
            ) : null}

            {pickError ? (
              <div className="mb-3">
                <Alert tone="error">{pickError}</Alert>
              </div>
            ) : null}

            {dataset === "students" ? (
              <>
                <StudentsTable
                  rows={students?.rows ?? []}
                  loading={loading}
                  showDate={showDate}
                  onOpen={setSelectedStudent}
                  onMessage={setMessageTarget}
                  picking={picking}
                  selectedIds={pickedRowIds}
                  onToggle={toggleRow}
                  onToggleAll={(ids) => {
                    setPickError(null);
                    setPickedRowIds(ids);
                  }}
                />
                <Pager
                  page={students?.page ?? 1}
                  perPage={students?.per_page ?? PER_PAGE}
                  total={students?.total ?? 0}
                  loading={loading}
                  onPage={setPage}
                />
              </>
            ) : null}

            {dataset === "classes" ? (
              <>
                <ClassesTable
                  rows={classes?.rows ?? []}
                  loading={loading}
                  showDate={showDate}
                  onMessage={setMessageTarget}
                  picking={picking}
                  selectedIds={pickedRowIds}
                  onToggle={toggleRow}
                  onToggleAll={(ids) => {
                    setPickError(null);
                    setPickedRowIds(ids);
                  }}
                />
                <Pager
                  page={classes?.page ?? 1}
                  perPage={classes?.per_page ?? PER_PAGE}
                  total={classes?.total ?? 0}
                  loading={loading}
                  onPage={setPage}
                />
              </>
            ) : null}

            {dataset === "alerts" ? (
              <AlertsList
                rows={alerts?.rows ?? []}
                loading={loading}
                onMessage={setMessageTarget}
                picking={picking}
                selectedIds={pickedAlertIds}
                onToggle={(id) => {
                  setPickError(null);
                  setPickedAlertIds((prev) =>
                    prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
                  );
                }}
              />
            ) : null}
          </GlassCard>
        </div>

        <aside className="space-y-4">
          <GlassCard>
            <CardTitle kicker="خلاصه محدوده" title="اعداد همین فیلتر" />
            {dataset === "classes" ? (
              <div className="grid grid-cols-2 gap-2">
                <MiniStat
                  label="تکمیل"
                  value={fa(classes?.counts.complete ?? 0)}
                  tone="emerald"
                  active={state.lists === "complete"}
                  onClick={() => patch({ lists: "complete" })}
                />
                <MiniStat
                  label="ناقص"
                  value={fa(classes?.counts.partial ?? 0)}
                  tone="amber"
                  active={state.lists === "partial"}
                  onClick={() => patch({ lists: "partial" })}
                />
                <MiniStat
                  label="پرنشده"
                  value={fa(classes?.counts.empty ?? 0)}
                  tone="rose"
                  active={state.lists === "empty"}
                  onClick={() => patch({ lists: "empty" })}
                />
                <MiniStat
                  label="ارسال دیر"
                  value={fa(classes?.counts.delayed ?? 0)}
                  tone="slate"
                  active={state.lists === "delayed"}
                  onClick={() => patch({ lists: "delayed" })}
                />
              </div>
            ) : dataset === "students" ? (
              <div className="grid grid-cols-2 gap-2">
                <MiniStat
                  label="حاضر"
                  value={fa(students?.counts.present ?? 0)}
                  tone="emerald"
                  active={state.status === "present"}
                  onClick={() => patch({ status: "present" })}
                />
                <MiniStat
                  label="تأخیر"
                  value={fa(students?.counts.late ?? 0)}
                  tone="amber"
                  active={state.status === "late"}
                  onClick={() => patch({ status: "late" })}
                />
                <MiniStat
                  label="غایب"
                  value={fa(students?.counts.absent ?? 0)}
                  tone="rose"
                  active={state.status === "absent"}
                  onClick={() => patch({ status: "absent" })}
                />
                <MiniStat
                  label="ثبت‌نشده"
                  value={fa(students?.counts.unchecked ?? 0)}
                  tone="slate"
                  active={state.status === "unchecked"}
                  onClick={() => patch({ status: "unchecked" })}
                />
                <MiniStat
                  label="خروج موقت"
                  value={fa(students?.counts.temporary_exit ?? 0)}
                  tone="indigo"
                  active={state.status === "temporary_exit"}
                  onClick={() => patch({ status: "temporary_exit" })}
                />
                <MiniStat
                  label="کل نفر-جلسه"
                  value={fa(students?.counts.total ?? 0)}
                  tone="teal"
                  active={state.status === "all"}
                  onClick={() => patch({ status: "all" })}
                />
              </div>
            ) : (
              <div className="grid grid-cols-3 gap-2">
                <MiniStat label="بحرانی" value={fa(alerts?.counts.critical ?? 0)} tone="rose" />
                <MiniStat label="اخطار" value={fa(alerts?.counts.warning ?? 0)} tone="amber" />
                <MiniStat label="اطلاعی" value={fa(alerts?.counts.info ?? 0)} tone="slate" />
              </div>
            )}
            <p className="mt-3 text-[11px] leading-6 text-slate-500">
              این اعداد بر اساس شعب، بازه و نوع کلاس انتخابی محاسبه می‌شود؛ با کلیک روی هر عدد،
              جدول همان گروه فیلتر می‌شود.
            </p>
          </GlassCard>

          <GlassCard>
            <CardTitle kicker="فیلترهای فعال" title="محدوده این فهرست" />
            <ul className="space-y-1.5 text-[11px] text-slate-600">
              <li>بازه: {dateLabel}</li>
              <li>شعبه: {branchLabel}</li>
              <li>
                نوع کلاس:{" "}
                {filters.options.delivery_modes.find((mode) => mode.key === state.deliveryMode)
                  ?.label ?? "حضوری و مجازی"}
              </li>
              {state.periodId ? (
                <li>
                  زنگ:{" "}
                  {filters.options.periods.find((period) => period.id === state.periodId)?.label ??
                    "—"}
                </li>
              ) : null}
              {state.classRoomId ? (
                <li>
                  کلاس:{" "}
                  {filters.options.class_rooms.find((room) => room.id === state.classRoomId)
                    ?.name ?? "—"}
                </li>
              ) : null}
            </ul>
            <Button
              className="mt-3"
              variant="secondary"
              block
              onClick={() => {
                filters.resetRowFilters();
                resetPicking();
              }}
            >
              پاک کردن فیلترهای ردیفی
            </Button>
          </GlassCard>
        </aside>
      </div>

      {selectedStudent ? (
        <StudentDrawer
          row={selectedStudent}
          absenceCap={absenceCap}
          onClose={() => setSelectedStudent(null)}
          onMessage={setMessageTarget}
        />
      ) : null}
      {messageTarget ? (
        <MessageModal target={messageTarget} onClose={() => setMessageTarget(null)} />
      ) : null}
    </div>
  );
}
