"use client";

import Link from "next/link";
import { FormEvent, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { FormActions, primarySubmitClass } from "@/components/forms/FormActions";
import { apiFieldErrors, FormErrorSummary } from "@/components/forms/FormErrorSummary";
import { Button } from "@/components/ui/Button";
import { Field, Input, Select, Textarea } from "@/components/ui/Field";
import { PersianDatePicker } from "@/components/ui/PersianDatePicker";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { UserAvatarUpload } from "@/components/ui/UserAvatarUpload";
import { ApiError, apiGet, apiPatch, apiPost, uploadUserAvatar } from "@/lib/api";
import { isCompletePersonIdentifier, isValidMobile, sanitizePersonIdentifier } from "@school/ui";
import type { GuardianLinkRow, PersonPayload, RelationshipOption } from "@/components/students/StudentGuardiansPanel";

type PersonForm = {
  user_id?: number | null;
  national_code: string;
  is_foreign_national: boolean;
  first_name: string;
  last_name: string;
  mobile: string;
  gender: string;
  birth_date: string;
  avatar_path: string;
  is_active: boolean;
  is_alive: boolean;
  landline: string;
  occupation: string;
  workplace: string;
  address: string;
  postal_code: string;
  notes: string;
  relationship: string;
  is_primary: boolean;
  receives_notifications: boolean;
  link_notes: string;
};

type GuardianFieldErrors = Partial<Record<keyof PersonForm, string>>;

const emptyForm = (): PersonForm => ({
  user_id: null,
  national_code: "",
  is_foreign_national: false,
  first_name: "",
  last_name: "",
  mobile: "",
  gender: "",
  birth_date: "",
  avatar_path: "",
  is_active: true,
  is_alive: true,
  landline: "",
  occupation: "",
  workplace: "",
  address: "",
  postal_code: "",
  notes: "",
  relationship: "father",
  is_primary: false,
  receives_notifications: false,
  link_notes: "",
});

function applyPerson(form: PersonForm, person: PersonPayload): PersonForm {
  return {
    ...form,
    user_id: person.id,
    national_code: person.national_code ?? form.national_code,
    is_foreign_national: Boolean(person.is_foreign_national),
    first_name: person.first_name ?? "",
    last_name: person.last_name ?? "",
    mobile: person.mobile ?? "",
    gender: person.gender ?? "",
    birth_date: person.birth_date ?? "",
    avatar_path: person.avatar_path ?? "",
    is_active: person.is_active !== false,
    is_alive: person.is_alive !== false,
    landline: person.landline ?? "",
    occupation: person.occupation ?? "",
    workplace: person.workplace ?? "",
    address: person.address ?? "",
    postal_code: person.postal_code ?? "",
    notes: person.notes ?? "",
  };
}

function validateGuardianForm(value: PersonForm, enrollMode = false): GuardianFieldErrors {
  const errors: GuardianFieldErrors = {};
  if (!isCompletePersonIdentifier(value.national_code, value.is_foreign_national)) {
    errors.national_code = value.is_foreign_national
      ? "شناسه اتباع الزامی است."
      : "کد ملی باید ۱۰ رقم باشد.";
  }
  if (!value.first_name.trim()) errors.first_name = "نام الزامی است.";
  if (!value.last_name.trim()) errors.last_name = "نام خانوادگی الزامی است.";
  if (!value.relationship) errors.relationship = "نسبت الزامی است.";
  if (value.mobile.trim()) {
    if (!isValidMobile(value.mobile)) errors.mobile = "موبایل معتبر نیست.";
  } else if (value.receives_notifications || enrollMode) {
    errors.mobile = enrollMode ? "موبایل ولی الزامی است." : "برای دریافت اعلان، موبایل الزامی است.";
  }
  return errors;
}

export function StudentGuardianForm({
  studentId,
  studentName,
  mode,
  linkId,
  enrollMode = false,
}: {
  studentId: number;
  studentName: string;
  mode: "create" | "edit";
  linkId?: number;
  enrollMode?: boolean;
}) {
  const router = useRouter();
  const isEdit = mode === "edit";
  const [form, setForm] = useState<PersonForm>(emptyForm);
  const [relationships, setRelationships] = useState<RelationshipOption[]>([]);
  const [loading, setLoading] = useState(true);
  const [lookupHit, setLookupHit] = useState<PersonPayload | null>(null);
  const [lookupChecked, setLookupChecked] = useState(isEdit);
  const [lookupLoading, setLookupLoading] = useState(false);
  const [identityUnlocked, setIdentityUnlocked] = useState(isEdit);
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [fieldErrors, setFieldErrors] = useState<GuardianFieldErrors>({});
  const [hasAnyNotifier, setHasAnyNotifier] = useState(false);
  const [mobileDupWarning, setMobileDupWarning] = useState<string | null>(null);
  const pendingAvatarRef = useRef<File | null>(null);

  const backHref = `/students/${studentId}/guardians`;

  const loadBase = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const data = await apiGet<{
        guardians: GuardianLinkRow[];
        relationships: RelationshipOption[];
      }>(`/students/${studentId}/guardians`);
      setRelationships(data.relationships ?? []);
      const rows = data.guardians ?? [];

      if (isEdit && linkId) {
        const row = rows.find((item) => item.id === linkId);
        if (!row) {
          setError("ارتباط ولی یافت نشد.");
          return;
        }
        const base = emptyForm();
        const withPerson = row.person ? applyPerson(base, row.person) : base;
        setForm({
          ...withPerson,
          relationship: row.relationship || data.relationships?.[0]?.code || "father",
          is_primary: row.is_primary,
          receives_notifications: row.receives_notifications,
          link_notes: row.notes ?? "",
        });
        setIdentityUnlocked(true);
        setLookupChecked(true);
      } else {
        const base = emptyForm();
        if (data.relationships?.[0]) base.relationship = data.relationships[0].code;
        const anyNotifier = rows.some((r) => r.receives_notifications);
        setHasAnyNotifier(anyNotifier);
        base.receives_notifications = !anyNotifier;
        base.is_primary = rows.every((r) => !r.is_primary);
        setForm(base);
      }
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
    } finally {
      setLoading(false);
    }
  }, [studentId, isEdit, linkId]);

  useEffect(() => {
    void loadBase();
  }, [loadBase]);

  useEffect(() => {
    if (isEdit) return;
    const code = form.national_code.trim();
    if (!isCompletePersonIdentifier(code, form.is_foreign_national)) {
      setLookupHit(null);
      setLookupChecked(false);
      setIdentityUnlocked(false);
      return;
    }

    const timer = window.setTimeout(() => {
      void (async () => {
        setLookupLoading(true);
        setError(null);
        try {
          const q = new URLSearchParams({
            national_code: code,
            is_foreign_national: form.is_foreign_national ? "1" : "0",
          });
          const data = await apiGet<{ found: boolean; person?: PersonPayload }>(`/persons/lookup?${q}`);
          setLookupChecked(true);
          if (data.found && data.person) {
            setLookupHit(data.person);
            setForm((current) => applyPerson(current, data.person!));
            setIdentityUnlocked(true);
          } else {
            setLookupHit(null);
            pendingAvatarRef.current = null;
            setForm((current) => ({
              ...current,
              user_id: null,
              first_name: "",
              last_name: "",
              mobile: "",
              gender: "",
              birth_date: "",
              avatar_path: "",
              landline: "",
              occupation: "",
              workplace: "",
              address: "",
              postal_code: "",
              notes: "",
              is_active: true,
              is_alive: true,
              receives_notifications: !hasAnyNotifier,
            }));
            setIdentityUnlocked(true);
          }
        } catch (err) {
          setLookupChecked(true);
          setIdentityUnlocked(true);
          setLookupHit(null);
          if (err instanceof ApiError) setError(err.message);
        } finally {
          setLookupLoading(false);
        }
      })();
    }, 350);

    return () => window.clearTimeout(timer);
  }, [form.national_code, form.is_foreign_national, isEdit, hasAnyNotifier]);

  const fieldsLocked = !isEdit && !identityUnlocked;

  useEffect(() => {
    if (fieldsLocked) {
      setMobileDupWarning(null);
      return;
    }
    const mobile = form.mobile.trim();
    if (!isValidMobile(mobile)) {
      setMobileDupWarning(null);
      return;
    }
    const timer = window.setTimeout(() => {
      void (async () => {
        try {
          const data = await apiGet<{ found: boolean; person?: PersonPayload }>(
            `/persons/lookup?mobile=${encodeURIComponent(mobile)}`,
          );
          if (data.found && data.person && data.person.id !== form.user_id) {
            setMobileDupWarning(
              `این شماره از قبل برای ${data.person.full_name ?? "شخص دیگری"} ثبت شده است. می‌توانید ادامه دهید.`,
            );
          } else {
            setMobileDupWarning(null);
          }
        } catch {
          setMobileDupWarning(null);
        }
      })();
    }, 400);
    return () => window.clearTimeout(timer);
  }, [form.mobile, form.user_id, fieldsLocked]);

  const patch = (partial: Partial<PersonForm>, errorKey?: keyof GuardianFieldErrors) => {
    setForm((current) => ({ ...current, ...partial }));
    if (errorKey) {
      setFieldErrors((prev) => {
        if (!prev[errorKey]) return prev;
        const next = { ...prev };
        delete next[errorKey];
        return next;
      });
    }
  };

  const displayName = `${form.first_name} ${form.last_name}`.trim() || "ولی";

  const identifierHint = useMemo(() => {
    if (isEdit) return null;
    if (!isCompletePersonIdentifier(form.national_code, form.is_foreign_national)) {
      return "ابتدا کد ملی / شناسه اتباع را کامل وارد کنید تا بقیه فیلدها فعال شوند.";
    }
    if (lookupLoading) return "در حال بررسی شناسه…";
    if (lookupChecked && lookupHit) {
      return `شخص موجود: ${lookupHit.full_name ?? "—"}${lookupHit.roles?.length ? ` · نقش‌ها: ${lookupHit.roles.join("، ")}` : ""}`;
    }
    if (lookupChecked && !lookupHit) return "شخص جدیدی است؛ اطلاعات را تکمیل کنید.";
    return null;
  }, [form.national_code, form.is_foreign_national, isEdit, lookupLoading, lookupChecked, lookupHit]);

  const submit = async (event: FormEvent) => {
    event.preventDefault();
    if (fieldsLocked) {
      setError("ابتدا یک شناسه معتبر وارد کنید.");
      return;
    }
    const localErrors = validateGuardianForm(form, enrollMode);
    if (Object.keys(localErrors).length > 0) {
      setFieldErrors(localErrors);
      setError(null);
      return;
    }
    setSaving(true);
    setError(null);
    setFieldErrors({});
    try {
      const payload = {
        user_id: form.user_id || undefined,
        national_code: form.national_code.trim(),
        is_foreign_national: form.is_foreign_national,
        first_name: form.first_name.trim(),
        last_name: form.last_name.trim(),
        mobile: form.mobile.trim() || null,
        gender: form.gender || null,
        birth_date: form.birth_date || null,
        is_active: form.is_active,
        is_alive: form.is_alive,
        landline: form.landline.trim() || null,
        occupation: form.occupation.trim() || null,
        workplace: form.workplace.trim() || null,
        address: form.address.trim() || null,
        postal_code: form.postal_code.trim() || null,
        notes: form.notes.trim() || null,
        relationship: form.relationship,
        is_primary: form.is_primary,
        receives_notifications: form.receives_notifications,
        link_notes: form.link_notes.trim() || null,
      };

      const saved = isEdit && linkId
        ? await apiPatch<{ guardian_user_id?: number; person?: PersonPayload | null }>(
            `/students/${studentId}/guardians/${linkId}`,
            payload,
          )
        : await apiPost<{ guardian_user_id?: number; person?: PersonPayload | null; warnings?: string[] }>(
            `/students/${studentId}/guardians`,
            payload,
          );

      const userId = saved.person?.id ?? saved.guardian_user_id ?? form.user_id;
      if (pendingAvatarRef.current && userId) {
        await uploadUserAvatar(userId, pendingAvatarRef.current);
      }
      const notice = saved.warnings?.[0] ?? mobileDupWarning;
      router.push(notice ? `${backHref}?warning=${encodeURIComponent(notice)}` : backHref);
    } catch (err) {
      const mapped = apiFieldErrors(err, {
        first_name: "first_name",
        last_name: "last_name",
        national_code: "national_code",
        mobile: "mobile",
        relationship: "relationship",
      });
      setFieldErrors(mapped.fields as GuardianFieldErrors);
      setError(mapped.general);
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return <PageContentSkeleton rows={6} />;
  }

  return (
    <form className="space-y-4" onSubmit={(e) => void submit(e)}>
      <div className="space-y-4 rounded-2xl border border-[var(--border)] bg-white p-4 shadow-card">
        <UserAvatarUpload
          name={displayName}
          avatarPath={form.avatar_path}
          userId={form.user_id ?? undefined}
          disabled={fieldsLocked}
          onAvatarChange={(path) => patch({ avatar_path: path ?? "" })}
          onPendingFile={(file) => {
            pendingAvatarRef.current = file;
          }}
        />
        <div className="grid gap-3 md:grid-cols-2">
          {!isEdit ? (
            <label className="flex items-center gap-2 text-sm md:col-span-2">
              <input
                type="checkbox"
                checked={form.is_foreign_national}
                onChange={(e) =>
                  patch({
                    is_foreign_national: e.target.checked,
                    national_code: sanitizePersonIdentifier(form.national_code, e.target.checked),
                    user_id: null,
                  }, "national_code")
                }
              />
              اتباع خارجی (شناسه غیر از کد ملی)
            </label>
          ) : null}
          <Field
            label={form.is_foreign_national ? "شناسه اتباع *" : "کد ملی *"}
            hint={identifierHint ?? "یکتا و غیرقابل تکرار"}
            error={fieldErrors.national_code}
          >
            <Input
              value={form.national_code}
              invalid={Boolean(fieldErrors.national_code)}
              inputMode={form.is_foreign_national ? "text" : "numeric"}
              maxLength={form.is_foreign_national ? 30 : 10}
              disabled={isEdit}
              onChange={(e) =>
                patch({
                  national_code: sanitizePersonIdentifier(e.target.value, form.is_foreign_national),
                  user_id: null,
                }, "national_code")
              }
              dir="ltr"
              className="text-left"
              autoFocus={!isEdit}
            />
          </Field>
          <Field
            label={enrollMode ? "موبایل *" : "موبایل"}
            error={fieldErrors.mobile}
            hint={enrollMode ? "برای ارسال اطلاعات پنل و تکمیل ثبت‌نام الزامی است" : form.receives_notifications ? "برای اعلان الزامی است" : "مثال: 09123456789"}
          >
            <Input
              value={form.mobile}
              invalid={Boolean(fieldErrors.mobile)}
              disabled={fieldsLocked}
              onChange={(e) => patch({ mobile: e.target.value.replace(/\D/g, "").slice(0, 11) }, "mobile")}
              dir="ltr"
              className="text-left"
              inputMode="tel"
              maxLength={11}
            />
          </Field>
          {mobileDupWarning ? (
            <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950 md:col-span-2">
              {mobileDupWarning}
            </div>
          ) : null}
          {!isEdit && lookupChecked && lookupHit ? (
            <div className="rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-950 md:col-span-2">
              این کد ملی قبلاً در سامانه استفاده شده است.
              <strong className="mr-1">{lookupHit.full_name}</strong>
              — اطلاعات بارگذاری شد؛ در صورت نیاز تکمیل کنید.
            </div>
          ) : null}
          <Field label="نام *" error={fieldErrors.first_name}>
            <Input
              value={form.first_name}
              invalid={Boolean(fieldErrors.first_name)}
              disabled={fieldsLocked}
              onChange={(e) => patch({ first_name: e.target.value }, "first_name")}
            />
          </Field>
          <Field label="نام خانوادگی *" error={fieldErrors.last_name}>
            <Input
              value={form.last_name}
              invalid={Boolean(fieldErrors.last_name)}
              disabled={fieldsLocked}
              onChange={(e) => patch({ last_name: e.target.value }, "last_name")}
            />
          </Field>
          <Field label="تلفن ثابت">
            <Input
              value={form.landline}
              disabled={fieldsLocked}
              onChange={(e) => patch({ landline: e.target.value })}
              dir="ltr"
              className="text-left"
            />
          </Field>
          <Field label="جنسیت">
            <div className="flex gap-4 pt-2">
              <label className="flex items-center gap-2 text-sm">
                <input
                  type="radio"
                  disabled={fieldsLocked}
                  checked={form.gender === "male"}
                  onChange={() => patch({ gender: "male" })}
                />
                آقا
              </label>
              <label className="flex items-center gap-2 text-sm">
                <input
                  type="radio"
                  disabled={fieldsLocked}
                  checked={form.gender === "female"}
                  onChange={() => patch({ gender: "female" })}
                />
                خانم
              </label>
            </div>
          </Field>
          <Field label="تاریخ تولد">
            <div className={fieldsLocked ? "pointer-events-none" : undefined}>
              <PersianDatePicker value={form.birth_date} onChange={(birth_date) => patch({ birth_date })} />
            </div>
          </Field>
          <Field label="نسبت با دانش‌آموز *" error={fieldErrors.relationship}>
            <Select
              value={form.relationship}
              invalid={Boolean(fieldErrors.relationship)}
              disabled={fieldsLocked}
              onChange={(e) => patch({ relationship: e.target.value }, "relationship")}
            >
              {relationships.map((rel) => (
                <option key={rel.code} value={rel.code}>
                  {rel.label}
                </option>
              ))}
            </Select>
          </Field>
          <Field label="شغل">
            <Input
              value={form.occupation}
              disabled={fieldsLocked}
              onChange={(e) => patch({ occupation: e.target.value })}
            />
          </Field>
          <Field label="محل کار">
            <Input
              value={form.workplace}
              disabled={fieldsLocked}
              onChange={(e) => patch({ workplace: e.target.value })}
            />
          </Field>
          <Field label="کد پستی">
            <Input
              value={form.postal_code}
              disabled={fieldsLocked}
              onChange={(e) => patch({ postal_code: e.target.value })}
              dir="ltr"
              className="text-left"
            />
          </Field>
          <div className="flex flex-col justify-end gap-3 text-sm">
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                disabled={fieldsLocked}
                checked={form.is_primary}
                onChange={(e) => patch({ is_primary: e.target.checked })}
              />
              ولی اصلی
            </label>
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                disabled={fieldsLocked}
                checked={form.receives_notifications}
                onChange={(e) => patch({ receives_notifications: e.target.checked }, "mobile")}
              />
              دریافت اعلان‌ها
            </label>
          </div>
          <div className="md:col-span-2">
            <Field label="آدرس">
              <Textarea
                value={form.address}
                disabled={fieldsLocked}
                onChange={(e) => patch({ address: e.target.value })}
                rows={2}
              />
            </Field>
          </div>
          <div className="md:col-span-2">
            <Field label="توضیحات شخص">
              <Textarea
                value={form.notes}
                disabled={fieldsLocked}
                onChange={(e) => patch({ notes: e.target.value })}
                rows={2}
              />
            </Field>
          </div>
          <div className="md:col-span-2">
            <Field label="توضیحات ارتباط">
              <Textarea
                value={form.link_notes}
                disabled={fieldsLocked}
                onChange={(e) => patch({ link_notes: e.target.value })}
                rows={2}
              />
            </Field>
          </div>
          <div className="flex flex-wrap gap-4 text-sm md:col-span-2">
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                disabled={fieldsLocked}
                checked={form.is_alive}
                onChange={(e) => patch({ is_alive: e.target.checked })}
              />
              در قید حیات
            </label>
            <label className="flex items-center gap-2">
              <input
                type="checkbox"
                disabled={fieldsLocked}
                checked={form.is_active}
                onChange={(e) => patch({ is_active: e.target.checked })}
              />
              فعال بودن شخص
            </label>
          </div>
        </div>

        <FormErrorSummary errors={fieldErrors} general={error} />
        <FormActions>
          <Button type="submit" disabled={saving || fieldsLocked} className={primarySubmitClass}>
            {saving ? "در حال ذخیره…" : isEdit ? "ذخیره" : enrollMode ? "ثبت و رفتن به اولیا" : "ثبت"}
          </Button>
          <Link href={backHref}>
            <Button type="button" variant="secondary" className="min-w-[8rem]">
              بازگشت
            </Button>
          </Link>
        </FormActions>
      </div>
    </form>
  );
}
