"use client";

import { useEffect, useMemo, useState } from "react";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { TimeInput } from "@/components/ui/Field";
import { ApiError } from "@/lib/api";
import {
  fetchAttendancePolicy,
  saveAttendancePolicy,
  type BoardQuery,
  type PolicyPayload,
} from "@/lib/attendance-report";
import { Drawer } from "./AttendanceShared";
import { fa } from "./AttendancePrimitives";

type Draft = {
  absence_cap_days: number;
  late_threshold_minutes: number;
  form_delay_minutes: number;
  morning_absence_cutoff: string;
};

/**
 * سیاست گزارشگیری روی `branch_attendance_settings` ذخیره می‌شود، نه کوکی
 * مرورگر؛ پس همه‌ی مدیران همان آستانه‌ها را می‌بینند.
 */
export function AttendancePolicyDrawer({
  query,
  canManage,
  onClose,
  onSaved,
}: {
  query: BoardQuery;
  canManage: boolean;
  onClose: () => void;
  onSaved: () => void;
}) {
  const [payload, setPayload] = useState<PolicyPayload | null>(null);
  const [draft, setDraft] = useState<Draft | null>(null);
  const [targets, setTargets] = useState<number[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    let cancelled = false;
    fetchAttendancePolicy(query)
      .then((data) => {
        if (cancelled) return;
        setPayload(data);
        const first = data.rows[0];
        setDraft({
          absence_cap_days: first?.absence_cap_days ?? data.effective.absence_cap_days,
          late_threshold_minutes:
            first?.late_threshold_minutes ?? data.effective.late_threshold_minutes,
          form_delay_minutes: first?.form_delay_minutes ?? data.effective.form_delay_minutes,
          morning_absence_cutoff: first?.morning_absence_cutoff ?? "07:45",
        });
        setTargets(data.rows.map((row) => row.branch_id));
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setError(err instanceof ApiError ? err.message : "خطا در دریافت سیاست گزارشگیری");
      });
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const changed = useMemo(() => {
    if (!payload || !draft) return false;
    const first = payload.rows[0];
    if (!first) return true;
    return (
      first.absence_cap_days !== draft.absence_cap_days ||
      first.late_threshold_minutes !== draft.late_threshold_minutes ||
      first.form_delay_minutes !== draft.form_delay_minutes ||
      first.morning_absence_cutoff !== draft.morning_absence_cutoff
    );
  }, [payload, draft]);

  async function save() {
    if (!draft) return;
    if (targets.length === 0) {
      setError("حداقل یک شعبه برای اعمال سیاست انتخاب کنید.");
      return;
    }
    setSaving(true);
    setError(null);
    try {
      const next = await saveAttendancePolicy({ branch_ids: targets, ...draft });
      setPayload(next);
      setNotice("سیاست گزارشگیری ذخیره شد.");
      onSaved();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "ذخیره سیاست ناموفق بود.");
    } finally {
      setSaving(false);
    }
  }

  return (
    <Drawer
      kicker="سیاست گزارشگیری"
      title="آستانه‌های گزارش حضور"
      subtitle={
        payload
          ? payload.scope === "branch"
            ? "این آستانه‌ها روی همین شعبه ذخیره می‌شود."
            : `اعمال روی ${fa(targets.length)} شعبه از ${fa(payload.rows.length)} شعبه محدوده`
          : undefined
      }
      onClose={onClose}
      footer={
        canManage ? (
          <>
            <Button block loading={saving} disabled={!draft || !changed} onClick={() => void save()}>
              ذخیره
            </Button>
            <Button block variant="secondary" onClick={onClose}>
              بازگشت
            </Button>
          </>
        ) : (
          <Button block variant="secondary" onClick={onClose}>
            بستن
          </Button>
        )
      }
    >
      {error ? (
        <div className="mb-3">
          <Alert tone="error">{error}</Alert>
        </div>
      ) : null}
      {notice ? (
        <div className="mb-3">
          <Alert tone="success">{notice}</Alert>
        </div>
      ) : null}

      {!draft || !payload ? (
        <p className="text-sm text-slate-400">در حال بارگذاری…</p>
      ) : (
        <>
          <p className="mb-4 text-xs leading-6 text-slate-500">
            این مقادیر روی تنظیمات حضور شعبه ذخیره می‌شود و مبنای محاسبه «تأخیر»، «در معرض خطر» و
            «ارسال دیر لیست» در همه گزارش‌ها است.
          </p>

          <NumberField
            label="سقف غیبت مجاز (روز در سال تحصیلی)"
            value={draft.absence_cap_days}
            min={1}
            max={365}
            disabled={!canManage}
            onChange={(absence_cap_days) => setDraft({ ...draft, absence_cap_days })}
          />
          <NumberField
            label="آستانه تأخیر ورود دانش‌آموز (دقیقه)"
            value={draft.late_threshold_minutes}
            min={1}
            max={240}
            disabled={!canManage}
            onChange={(late_threshold_minutes) => setDraft({ ...draft, late_threshold_minutes })}
          />
          <NumberField
            label="آستانه تأخیر ارسال فرم حضور معلم (دقیقه)"
            value={draft.form_delay_minutes}
            min={1}
            max={240}
            disabled={!canManage}
            onChange={(form_delay_minutes) => setDraft({ ...draft, form_delay_minutes })}
          />
          <label className="mb-3 block text-sm font-bold text-slate-600">
            ساعت بستن غیبت صبحگاهی
            <div className="mt-1">
              <TimeInput
                value={draft.morning_absence_cutoff}
                disabled={!canManage}
                onChange={(morning_absence_cutoff) => setDraft({ ...draft, morning_absence_cutoff })}
              />
            </div>
          </label>

          {payload.rows.length > 1 ? (
            <div className="mt-4">
              <p className="mb-2 text-xs font-bold text-slate-500">اعمال روی کدام شعب؟</p>
              <ul className="grid grid-cols-2 gap-2">
                {payload.rows.map((row) => {
                  const on = targets.includes(row.branch_id);
                  return (
                    <li key={row.branch_id}>
                      <button
                        type="button"
                        disabled={!canManage}
                        onClick={() =>
                          setTargets((prev) =>
                            on
                              ? prev.filter((id) => id !== row.branch_id)
                              : [...prev, row.branch_id],
                          )
                        }
                        className={`w-full rounded-xl px-2.5 py-2 text-right text-[11px] font-bold ring-1 transition ${
                          on
                            ? "bg-teal-50 text-teal-900 ring-teal-200"
                            : "bg-slate-50 text-slate-600 ring-transparent"
                        }`}
                      >
                        <span className="block truncate">{row.branch_name ?? "شعبه"}</span>
                        <span className="text-[10px] font-normal opacity-70">
                          سقف {fa(row.absence_cap_days)} · تأخیر {fa(row.late_threshold_minutes)} ·
                          فرم {fa(row.form_delay_minutes)}
                        </span>
                      </button>
                    </li>
                  );
                })}
              </ul>
            </div>
          ) : null}

          {!canManage ? (
            <p className="mt-4 rounded-2xl bg-slate-50 px-3 py-2 text-[11px] text-slate-500">
              برای تغییر این آستانه‌ها به دسترسی «مدیریت سیاست حضور» نیاز دارید.
            </p>
          ) : changed ? (
            <p className="mt-4 rounded-2xl bg-amber-50 px-3 py-2 text-[11px] font-bold text-amber-800">
              تغییرات ذخیره نشده است.
            </p>
          ) : null}
        </>
      )}
    </Drawer>
  );
}

function NumberField({
  label,
  value,
  min,
  max,
  disabled,
  onChange,
}: {
  label: string;
  value: number;
  min: number;
  max: number;
  disabled?: boolean;
  onChange: (value: number) => void;
}) {
  return (
    <label className="mb-3 block text-sm font-bold text-slate-600">
      {label}
      <input
        type="number"
        min={min}
        max={max}
        value={value}
        disabled={disabled}
        onChange={(event) => {
          const next = Number(event.target.value);
          if (Number.isFinite(next)) onChange(Math.min(max, Math.max(min, next)));
        }}
        className="mt-1 w-full rounded-xl border border-slate-200 px-3 py-2 disabled:bg-slate-50"
      />
    </label>
  );
}
