"use client";

import Link from "next/link";
import { useEffect, useMemo, useState, type Dispatch, type ReactNode, type SetStateAction } from "react";
import { FormActions } from "@/components/forms/FormActions";
import { FormErrorSummary } from "@/components/forms/FormErrorSummary";
import { Field, Input, Select } from "@/components/ui/Field";
import { UserAvatarUpload } from "@/components/ui/UserAvatarUpload";
import { PersianDatePicker } from "@/components/ui/PersianDatePicker";
import { AdminUser, apiGet, getStoredUser } from "@/lib/api";
import { isCompletePersonIdentifier, sanitizePersonIdentifier, validateMobile } from "@school/ui";
import type { PersonPayload } from "@/components/students/StudentGuardiansPanel";

export interface StaffFormValues {
  first_name: string;
  last_name: string;
  email: string;
  mobile: string;
  national_code: string;
  is_foreign_national: boolean;
  personnel_code: string;
  employment_type: string;
  gender: string;
  birth_date: string;
  avatar_path: string;
  password: string;
  is_active: boolean;
  existing_user_id: number | null;
}

export const emptyStaffForm = (): StaffFormValues => ({
  first_name: "",
  last_name: "",
  email: "",
  mobile: "",
  national_code: "",
  is_foreign_national: false,
  personnel_code: "",
  employment_type: "",
  gender: "",
  birth_date: "",
  avatar_path: "",
  password: "",
  is_active: true,
  existing_user_id: null,
});

export type StaffFormFieldErrors = Partial<Record<keyof StaffFormValues, string>>;

export function isPortalOnlyPerson(roles?: string[] | null): boolean {
  if (!roles || roles.length === 0) return false;
  return roles.every((role) => role === "student" || role === "parent");
}

export function validateStaffForm(value: StaffFormValues, options?: { allowExisting?: boolean }): StaffFormFieldErrors {
  const errors: StaffFormFieldErrors = {};
  if (!value.first_name.trim()) errors.first_name = "نام الزامی است.";
  if (!value.last_name.trim()) errors.last_name = "نام خانوادگی الزامی است.";
  if (!isCompletePersonIdentifier(value.national_code, value.is_foreign_national)) {
    errors.national_code = value.is_foreign_national
      ? "شناسه اتباع الزامی است."
      : "کد ملی باید ۱۰ رقم باشد.";
  }
  if (!options?.allowExisting && value.existing_user_id) {
    errors.national_code = "این کد ملی قبلاً در سامانه ثبت شده است.";
  }
  const mobileError = validateMobile(value.mobile);
  if (mobileError) errors.mobile = mobileError;
  return errors;
}

export function staffFromApi(data: {
  id?: number;
  first_name?: string | null;
  last_name?: string | null;
  name?: string;
  email?: string;
  mobile?: string | null;
  national_code?: string | null;
  is_foreign_national?: boolean;
  personnel_code?: string | null;
  employment_type?: string | null;
  gender?: string | null;
  birth_date?: string | null;
  avatar_path?: string | null;
  is_active?: boolean;
}): StaffFormValues {
  let first = data.first_name ?? "";
  let last = data.last_name ?? "";
  if ((!first || !last) && data.name) {
    const parts = data.name.trim().split(/\s+/);
    first = first || parts[0] || "";
    last = last || parts.slice(1).join(" ") || "";
  }

  return {
    first_name: first,
    last_name: last,
    email: data.email ?? "",
    mobile: data.mobile ?? "",
    national_code: data.national_code ?? "",
    is_foreign_national: Boolean(data.is_foreign_national),
    personnel_code: data.personnel_code ?? "",
    employment_type: data.employment_type ?? "",
    gender: data.gender ?? "",
    birth_date: data.birth_date ?? "",
    avatar_path: data.avatar_path ?? "",
    password: "",
    is_active: data.is_active ?? true,
    existing_user_id: data.id ?? null,
  };
}

function applyLookupPerson(form: StaffFormValues, person: PersonPayload): StaffFormValues {
  return {
    ...form,
    existing_user_id: person.id,
    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 ?? "",
    personnel_code: person.personnel_code ?? "",
    employment_type: person.employment_type ?? "",
    national_code: person.national_code ?? form.national_code,
    is_foreign_national: Boolean(person.is_foreign_national),
  };
}

export function toStaffPayload(form: StaffFormValues, mode: "create" | "edit") {
  const payload: Record<string, unknown> = {
    first_name: form.first_name.trim(),
    last_name: form.last_name.trim(),
    mobile: form.mobile.trim(),
    national_code: form.national_code.trim(),
    is_foreign_national: form.is_foreign_national,
    personnel_code: form.personnel_code.trim() || null,
    employment_type: form.employment_type || null,
    gender: form.gender || null,
    birth_date: form.birth_date || null,
  };

  if (form.email.trim()) {
    payload.email = form.email.trim();
  }

  if (form.password.trim()) {
    payload.password = form.password.trim();
  }

  if (mode === "edit") {
    payload.is_active = form.is_active;
  }

  return payload;
}

export function StaffForm({
  value,
  onChange,
  mode = "create",
  userId,
  onPendingAvatarFile,
  errors = {},
  onErrorsChange,
  actions,
  generalError,
  onLookupPerson,
}: {
  value: StaffFormValues;
  onChange: (v: StaffFormValues) => void;
  mode?: "create" | "edit";
  userId?: number;
  onPendingAvatarFile?: (file: File | null) => void;
  errors?: StaffFormFieldErrors;
  onErrorsChange?: Dispatch<SetStateAction<StaffFormFieldErrors>>;
  actions?: ReactNode;
  generalError?: string | null;
  onLookupPerson?: (person: PersonPayload | null) => void;
}) {
  const [foreignEnabled, setForeignEnabled] = useState(false);
  const [lookupHit, setLookupHit] = useState<PersonPayload | null>(null);
  const [lookupChecked, setLookupChecked] = useState(mode === "edit");
  const [lookupLoading, setLookupLoading] = useState(false);
  const [identityUnlocked, setIdentityUnlocked] = useState(mode === "edit");

  useEffect(() => {
    const user = getStoredUser<AdminUser>();
    if (!user?.organization_id) return;
    apiGet<{ value: boolean }>(
      `/settings/resolve?key=staff.foreign_nationals_enabled&organization_id=${user.organization_id}`,
    )
      .then((row) => setForeignEnabled(Boolean(row.value)))
      .catch(() => setForeignEnabled(false));
  }, []);

  useEffect(() => {
    if (mode === "edit") return;
    const code = value.national_code.trim();
    if (!isCompletePersonIdentifier(code, value.is_foreign_national)) {
      setLookupHit(null);
      onLookupPerson?.(null);
      setLookupChecked(false);
      setIdentityUnlocked(false);
      return;
    }

    const timer = window.setTimeout(() => {
      void (async () => {
        setLookupLoading(true);
        try {
          const q = new URLSearchParams({
            national_code: code,
            is_foreign_national: value.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);
            onLookupPerson?.(data.person);
            onChange(applyLookupPerson(value, data.person));
            setIdentityUnlocked(true);
          } else {
            setLookupHit(null);
            onLookupPerson?.(null);
            onPendingAvatarFile?.(null);
            onChange({
              ...value,
              existing_user_id: null,
              first_name: "",
              last_name: "",
              mobile: "",
              gender: "",
              birth_date: "",
              avatar_path: "",
              email: "",
              personnel_code: "",
              employment_type: "",
              password: "",
              is_active: true,
            });
            setIdentityUnlocked(true);
          }
        } catch {
          setLookupChecked(true);
          setIdentityUnlocked(true);
          setLookupHit(null);
          onLookupPerson?.(null);
        } finally {
          setLookupLoading(false);
        }
      })();
    }, 350);

    return () => window.clearTimeout(timer);
    // Lookup should only re-run when identity changes, not when other fields patch.
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value.national_code, value.is_foreign_national, mode]);

  const patch = (partial: Partial<StaffFormValues>, errorKey?: keyof StaffFormFieldErrors) => {
    onChange({ ...value, ...partial });
    if (errorKey) {
      onErrorsChange?.((prev) => {
        if (!prev[errorKey]) return prev;
        const next = { ...prev };
        delete next[errorKey];
        return next;
      });
    }
  };

  const fieldsLocked = mode === "create" && !identityUnlocked;
  const displayName = `${value.first_name} ${value.last_name}`.trim() || "کاربر";

  const identifierHint = useMemo(() => {
    if (mode === "edit") {
      return value.is_foreign_national ? "کد فیدا یا شماره گذرنامه (حداکثر ۳۰ کاراکتر)" : "یکتا و غیرقابل تکرار";
    }
    if (!isCompletePersonIdentifier(value.national_code, value.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 "یکتا و غیرقابل تکرار";
  }, [
    mode,
    value.national_code,
    value.is_foreign_national,
    lookupLoading,
    lookupChecked,
    lookupHit,
  ]);

  return (
    <div className="space-y-4">
    <div className="space-y-4 rounded-2xl border border-[var(--border)] bg-white p-4 shadow-card">
      <UserAvatarUpload
        name={displayName}
        avatarPath={value.avatar_path}
        userId={userId}
        disabled={fieldsLocked}
        onAvatarChange={(path) => patch({ avatar_path: path ?? "" })}
        onPendingFile={onPendingAvatarFile}
      />
      <div className="grid gap-3 md:grid-cols-2">
        {foreignEnabled || value.is_foreign_national ? (
          <label className="flex items-center gap-2 text-sm md:col-span-2">
            <input
              type="checkbox"
              checked={value.is_foreign_national}
              disabled={mode === "edit"}
              onChange={(e) =>
                patch({
                  is_foreign_national: e.target.checked,
                  national_code: sanitizePersonIdentifier(value.national_code, e.target.checked),
                  existing_user_id: null,
                }, "national_code")
              }
            />
            کارمند اتباع
          </label>
        ) : null}
        <Field
          label={value.is_foreign_national ? "شناسه اتباع *" : "کد ملی *"}
          hint={identifierHint}
          error={errors.national_code}
        >
          <Input
            value={value.national_code}
            invalid={Boolean(errors.national_code)}
            disabled={mode === "edit"}
            onChange={(e) =>
              patch(
                {
                  national_code: sanitizePersonIdentifier(e.target.value, value.is_foreign_national),
                  existing_user_id: null,
                },
                "national_code",
              )
            }
            dir="ltr"
            className="text-left"
            required
            inputMode={value.is_foreign_national ? "text" : "numeric"}
            maxLength={value.is_foreign_national ? 30 : 10}
            autoFocus={mode === "create"}
          />
        </Field>
        <Field label="ایمیل" hint="اختیاری" error={errors.email}>
          <Input
            type="email"
            value={value.email}
            invalid={Boolean(errors.email)}
            disabled={fieldsLocked}
            onChange={(e) => patch({ email: e.target.value }, "email")}
            dir="ltr"
            className="text-left"
          />
        </Field>
        {mode === "create" && 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">
            {isPortalOnlyPerson(lookupHit.roles) ? (
              <>
                این کد ملی متعلق به دانش‌آموز یا ولی است و از این صفحه به‌عنوان کارمند قابل ثبت نیست.
                {lookupHit.student_id ? (
                  <Link href={`/students/${lookupHit.student_id}/edit`} className="mr-2 font-semibold text-teal-800 hover:underline">
                    مشاهده دانش‌آموز
                  </Link>
                ) : null}
              </>
            ) : (
              <>
                این شخص قبلاً ثبت شده است.
                <strong className="mr-1">{lookupHit.full_name}</strong>
                اطلاعات را در صورت نیاز اصلاح کنید؛ پس از ثبت به صفحه نقش‌ها می‌روید تا مدرسه جدید اضافه شود. دسترسی مدارس قبلی حفظ می‌شود.
                <Link href={`/staff/${lookupHit.id}/roles`} className="mr-2 font-semibold text-teal-800 hover:underline">
                  اختصاص نقش و مدرسه
                </Link>
                {(value.first_name !== (lookupHit.first_name ?? "") ||
                  value.last_name !== (lookupHit.last_name ?? "") ||
                  value.mobile !== (lookupHit.mobile ?? "")) && (
                  <ul className="mt-2 list-disc pr-5 text-xs leading-6">
                    {value.first_name !== (lookupHit.first_name ?? "") ? (
                      <li>نام: {lookupHit.first_name || "—"} ← {value.first_name || "—"}</li>
                    ) : null}
                    {value.last_name !== (lookupHit.last_name ?? "") ? (
                      <li>نام خانوادگی: {lookupHit.last_name || "—"} ← {value.last_name || "—"}</li>
                    ) : null}
                    {value.mobile !== (lookupHit.mobile ?? "") ? (
                      <li>موبایل: {lookupHit.mobile || "—"} ← {value.mobile || "—"}</li>
                    ) : null}
                  </ul>
                )}
              </>
            )}
          </div>
        ) : null}
        <Field label="نام *" error={errors.first_name}>
          <Input
            value={value.first_name}
            invalid={Boolean(errors.first_name)}
            disabled={fieldsLocked}
            onChange={(e) => patch({ first_name: e.target.value }, "first_name")}
          />
        </Field>
        <Field label="نام خانوادگی *" error={errors.last_name}>
          <Input
            value={value.last_name}
            invalid={Boolean(errors.last_name)}
            disabled={fieldsLocked}
            onChange={(e) => patch({ last_name: e.target.value }, "last_name")}
          />
        </Field>
        <Field label="موبایل *" hint="الزامی — مثال: 09123456789" error={errors.mobile}>
          <Input
            value={value.mobile}
            invalid={Boolean(errors.mobile)}
            disabled={fieldsLocked}
            onChange={(e) => patch({ mobile: e.target.value.replace(/\D/g, "").slice(0, 11) }, "mobile")}
            dir="ltr"
            className="text-left"
            required
            inputMode="tel"
            maxLength={11}
          />
        </Field>
        <Field label="کد پرسنلی">
          <Input
            value={value.personnel_code}
            disabled={fieldsLocked}
            onChange={(e) => patch({ personnel_code: e.target.value })}
            dir="ltr"
            className="text-left"
          />
        </Field>
        <Field label="نوع همکاری">
          <Select
            value={value.employment_type}
            disabled={fieldsLocked}
            onChange={(e) => patch({ employment_type: e.target.value })}
          >
            <option value="">انتخاب کنید</option>
            <option value="official">رسمی</option>
            <option value="contractual">قراردادی</option>
          </Select>
        </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={value.gender === "male"}
                onChange={() => patch({ gender: "male" })}
              />
              آقا
            </label>
            <label className="flex items-center gap-2 text-sm">
              <input
                type="radio"
                disabled={fieldsLocked}
                checked={value.gender === "female"}
                onChange={() => patch({ gender: "female" })}
              />
              خانم
            </label>
          </div>
        </Field>
        <Field label="تاریخ تولد">
          <div className={fieldsLocked ? "pointer-events-none" : undefined}>
            <PersianDatePicker
              value={value.birth_date}
              onChange={(birth_date) => patch({ birth_date })}
            />
          </div>
        </Field>
        <Field
          label={mode === "create" ? "رمز عبور (اختیاری)" : "رمز جدید (اختیاری)"}
          hint={
            mode === "create"
              ? "اگر خالی بماند سیستم رمز اولیه می‌سازد"
              : "فقط در صورت نیاز به تغییر رمز پر کنید"
          }
        >
          <Input
            type="password"
            value={value.password}
            disabled={fieldsLocked}
            onChange={(e) => patch({ password: e.target.value })}
            dir="ltr"
            className="text-left"
            autoComplete="new-password"
          />
        </Field>
      </div>

      {mode === "edit" ? (
        <label className="flex items-center justify-between rounded-xl border border-[var(--border)] px-3 py-2 text-sm">
          <span>فعال</span>
          <input
            type="checkbox"
            checked={value.is_active}
            onChange={(e) => patch({ is_active: e.target.checked })}
          />
        </label>
      ) : null}

      <FormErrorSummary errors={errors} general={generalError} />
      {actions ? <FormActions>{actions}</FormActions> : null}
    </div>
    </div>
  );
}
