"use client";

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

export interface StudentFormValues {
  branch_id: string;
  education_stage_id: string;
  grade_level_id: string;
  study_field_id: string;
  academic_year_id: string;
  first_name: string;
  last_name: string;
  father_name: string;
  national_code: string;
  is_foreign_national: boolean;
  birth_date: string;
  birth_place: string;
  gender: string;
  guardian_mobile: string;
  landline: string;
  student_mobile: string;
  student_uses_guardian_mobile: boolean;
  email: string;
  home_address: string;
  notes: string;
  avatar_path: string;
  existing_user_id: number | null;
}

export const emptyStudentForm = (): StudentFormValues => ({
  branch_id: "",
  education_stage_id: "",
  grade_level_id: "",
  study_field_id: "",
  academic_year_id: "",
  first_name: "",
  last_name: "",
  father_name: "",
  national_code: "",
  is_foreign_national: false,
  birth_date: "",
  birth_place: "",
  gender: "",
  guardian_mobile: "",
  landline: "",
  student_mobile: "",
  student_uses_guardian_mobile: false,
  email: "",
  home_address: "",
  notes: "",
  avatar_path: "",
  existing_user_id: null,
});

export type StudentFormFieldErrors = Partial<Record<keyof StudentFormValues, string>>;

export function studentEnrollmentLockMessage(
  person: PersonPayload | null | undefined,
  branchId: string,
): string | null {
  if (!person?.student_id) return null;
  const active = person.active_enrollment;
  if (!active) return null;
  if (branchId && Number(branchId) === active.branch_id) {
    return "این دانش‌آموز هم‌اکنون در این مدرسه ثبت است.";
  }
  const school = active.branch_name?.trim() || "دیگر";
  return `این دانش‌آموز هم‌اکنون در مدرسه «${school}» ثبت است. باید توسط همان مدرسه برای مدرسه شما آزاد شود؛ تا آن زمان امکان افزودن وجود ندارد.`;
}

export function validateStudentForm(value: StudentFormValues, options?: { allowExisting?: boolean }): StudentFormFieldErrors {
  const errors: StudentFormFieldErrors = {};
  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 = "این کاربر از قبل وجود دارد.";
  }
  if (!value.student_uses_guardian_mobile && value.student_mobile.trim()) {
    const mobileError = validateMobile(value.student_mobile.trim());
    if (mobileError) errors.student_mobile = mobileError;
  }
  return errors;
}

export function StudentForm({
  value,
  onChange,
  errors = {},
  onErrorsChange,
  actions,
  generalError,
  userId,
  onPendingAvatarFile,
  onLookupPerson,
  mode = "create",
}: {
  value: StudentFormValues;
  onChange: (v: StudentFormValues) => void;
  errors?: StudentFormFieldErrors;
  onErrorsChange?: Dispatch<SetStateAction<StudentFormFieldErrors>>;
  actions?: ReactNode;
  generalError?: string | null;
  userId?: number;
  onPendingAvatarFile?: (file: File | null) => void;
  onLookupPerson?: (person: PersonPayload | null) => void;
  mode?: "create" | "edit";
}) {
  const [branches, setBranches] = useState<BranchItem[]>([]);
  const [stages, setStages] = useState<EducationStage[]>([]);
  const [years, setYears] = useState<AcademicYear[]>([]);
  const [studyFields, setStudyFields] = useState<Array<{ id: number; name: string }>>([]);
  const [foreignEnabled, setForeignEnabled] = useState(false);
  const [lookupHit, setLookupHit] = useState<PersonPayload | null>(null);
  const [lookupChecked, setLookupChecked] = useState(mode === "edit");
  const [lookupLoading, setLookupLoading] = useState(false);

  useEffect(() => {
    Promise.all([
      apiGet<BranchItem[]>("/branches"),
      apiGet<AcademicYear[]>("/academic-years?active_only=1"),
    ])
      .then(([b, y]) => {
        setBranches(b);
        setYears(y);
        const next = { ...value };
        let changed = false;
        if (!next.academic_year_id) {
          const current = y.find((item) => item.is_current) ?? y[0];
          if (current) {
            next.academic_year_id = String(current.id);
            changed = true;
          }
        }
        if (!next.branch_id && b.length === 1) {
          next.branch_id = String(b[0].id);
          changed = true;
        }
        if (changed) onChange(next);
      })
      .catch(() => undefined);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

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

  useEffect(() => {
    if (!value.branch_id) {
      setStages([]);
      return;
    }
    apiGet<EducationStage[]>(`/education-stages?branch_id=${value.branch_id}`)
      .then(setStages)
      .catch(() => setStages([]));
  }, [value.branch_id]);

  const grades: GradeLevel[] =
    stages.find((s) => String(s.id) === value.education_stage_id)?.grade_levels ?? [];

  useEffect(() => {
    if (!value.grade_level_id) {
      setStudyFields([]);
      return;
    }
    apiGet<Array<{ id: number; name: string }>>(
      `/study-fields?grade_level_id=${value.grade_level_id}&branch_id=${value.branch_id}`,
    )
      .then(setStudyFields)
      .catch(() => setStudyFields([]));
  }, [value.grade_level_id, value.branch_id]);

  useEffect(() => {
    if (mode === "edit") return;
    const code = value.national_code.trim();
    if (!isCompletePersonIdentifier(code, value.is_foreign_national)) {
      setLookupHit(null);
      onLookupPerson?.(null);
      setLookupChecked(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({
              ...value,
              existing_user_id: data.person.id,
              first_name: data.person.first_name ?? value.first_name,
              last_name: data.person.last_name ?? value.last_name,
              gender: data.person.gender ?? value.gender,
              birth_date: data.person.birth_date ?? value.birth_date,
              avatar_path: data.person.avatar_path ?? value.avatar_path,
              student_mobile: data.person.mobile ?? value.student_mobile,
            });
          } else {
            setLookupHit(null);
            onLookupPerson?.(null);
            onChange({ ...value, existing_user_id: null });
          }
        } catch {
          setLookupChecked(true);
          setLookupHit(null);
          onLookupPerson?.(null);
        } finally {
          setLookupLoading(false);
        }
      })();
    }, 350);

    return () => window.clearTimeout(timer);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value.national_code, value.is_foreign_national, mode]);

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

  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 "این کاربر از قبل وجود دارد.";
    return "یکتا و غیرقابل تکرار";
  }, [
    mode,
    value.national_code,
    value.is_foreign_national,
    lookupLoading,
    lookupChecked,
    lookupHit,
  ]);

  const displayName = `${value.first_name} ${value.last_name}`.trim() || "دانش‌آموز";
  const lockMessage =
    mode === "create" ? studentEnrollmentLockMessage(lookupHit, value.branch_id) : null;
  const duplicateHref = lookupHit?.student_id
    ? `/students/${lookupHit.student_id}/edit`
    : lookupHit
      ? `/staff/${lookupHit.id}/edit`
      : null;

  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}
          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}
                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
              inputMode={value.is_foreign_national ? "text" : "numeric"}
              maxLength={value.is_foreign_national ? 30 : 10}
              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
            />
          </Field>
          {mode === "create" && lookupChecked && lookupHit ? (
            <div
              className={`rounded-xl border px-4 py-3 text-sm md:col-span-2 ${
                lockMessage
                  ? "border-red-200 bg-red-50 text-red-950"
                  : "border-amber-200 bg-amber-50 text-amber-950"
              }`}
            >
              {lockMessage ? (
                lockMessage
              ) : lookupHit.student_id && !lookupHit.active_enrollment ? (
                <>
                  این دانش‌آموز قبلاً ثبت شده و از مدرسه قبلی آزاد شده است. با ثبت، در مدرسه انتخاب‌شده اضافه می‌شود.
                  <strong className="mr-1">{lookupHit.full_name}</strong>
                </>
              ) : (
                <>
                  این کاربر از قبل وجود دارد.
                  <strong className="mr-1">{lookupHit.full_name}</strong>
                  {lookupHit.roles?.length ? ` · نقش‌ها: ${lookupHit.roles.join("، ")}` : ""}
                </>
              )}
              {duplicateHref && !lockMessage ? (
                <Link href={duplicateHref} className="mr-2 font-semibold text-teal-800 hover:underline">
                  {lookupHit.student_id ? "ویرایش دانش‌آموز" : "مشاهده شخص"}
                </Link>
              ) : null}
            </div>
          ) : null}
          <Field label="پست الکترونیکی" hint="اختیاری" error={errors.email}>
            <Input
              value={value.email}
              placeholder="example@gmail.com"
              invalid={Boolean(errors.email)}
              onChange={(e) => patch({ email: e.target.value }, "email")}
              dir="ltr"
              className="text-left"
            />
          </Field>
          <Field label="نام *" error={errors.first_name}>
            <Input
              value={value.first_name}
              invalid={Boolean(errors.first_name)}
              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)}
              onChange={(e) => patch({ last_name: e.target.value }, "last_name")}
            />
          </Field>
          <Field label="نام پدر">
            <Input value={value.father_name} onChange={(e) => patch({ father_name: e.target.value })} />
          </Field>
          <Field label="مدرسه">
            <Select
              value={value.branch_id}
              onChange={(e) =>
                patch({
                  branch_id: e.target.value,
                  education_stage_id: "",
                  grade_level_id: "",
                  study_field_id: "",
                })
              }
            >
              <option value="">لطفا انتخاب کنید</option>
              {branches.map((b) => (
                <option key={b.id} value={b.id}>{b.name}</option>
              ))}
            </Select>
          </Field>
          <Field label="سال تحصیلی">
            <Select value={value.academic_year_id} onChange={(e) => patch({ academic_year_id: e.target.value })}>
              <option value="">لطفا انتخاب کنید</option>
              {years.map((y) => (
                <option key={y.id} value={y.id}>{y.title}{y.is_current ? " (جاری)" : ""}</option>
              ))}
            </Select>
          </Field>
          <Field label="مقطع تحصیلی (اختیاری)">
            <Select
              value={value.education_stage_id}
              onChange={(e) =>
                patch({ education_stage_id: e.target.value, grade_level_id: "", study_field_id: "" })
              }
              disabled={!value.branch_id}
            >
              <option value="">{value.branch_id ? "اختیاری" : "ابتدا مدرسه را انتخاب کنید"}</option>
              {stages.map((s) => (
                <option key={s.id} value={s.id}>{s.name}</option>
              ))}
            </Select>
          </Field>
          <Field label="پایه تحصیلی (اختیاری)">
            <Select
              value={value.grade_level_id}
              onChange={(e) => patch({ grade_level_id: e.target.value, study_field_id: "" })}
              disabled={!value.education_stage_id}
            >
              <option value="">بدون پایه</option>
              {grades.map((g) => (
                <option key={g.id} value={g.id}>{g.name}</option>
              ))}
            </Select>
          </Field>
          {studyFields.length > 0 ? (
            <Field label="رشته تحصیلی (اختیاری)">
              <Select
                value={value.study_field_id}
                onChange={(e) => patch({ study_field_id: e.target.value })}
              >
                <option value="">بدون رشته</option>
                {studyFields.map((f) => (
                  <option key={f.id} value={f.id}>{f.name}</option>
                ))}
              </Select>
            </Field>
          ) : null}
          <Field label="شهر محل تولد">
            <Input value={value.birth_place} onChange={(e) => patch({ birth_place: e.target.value })} />
          </Field>
          <Field label="تاریخ تولد">
            <PersianDatePicker value={value.birth_date} onChange={(birth_date) => patch({ birth_date })} />
          </Field>
          <Field label="جنسیت">
            <div className="flex gap-4 pt-2">
              <label className="flex items-center gap-2 text-sm">
                <input type="radio" checked={value.gender === "male"} onChange={() => patch({ gender: "male" })} />
                آقا
              </label>
              <label className="flex items-center gap-2 text-sm">
                <input type="radio" checked={value.gender === "female"} onChange={() => patch({ gender: "female" })} />
                خانم
              </label>
            </div>
          </Field>
          <div className="space-y-2">
          <Field label="تلفن همراه دانش‌آموز" hint="اختیاری" error={errors.student_mobile}>
            <Input
              value={value.student_mobile}
              invalid={Boolean(errors.student_mobile)}
              disabled={value.student_uses_guardian_mobile}
              onChange={(e) => patch({ student_mobile: e.target.value.replace(/\D/g, "").slice(0, 11) }, "student_mobile")}
              inputMode="tel"
              maxLength={11}
              dir="ltr"
              className="text-left"
            />
          </Field>
          <label className="flex items-center gap-2 text-xs text-[var(--muted)]">
            <input
              type="checkbox"
              checked={value.student_uses_guardian_mobile}
              onChange={(e) =>
                patch({
                  student_uses_guardian_mobile: e.target.checked,
                  student_mobile: e.target.checked ? "" : value.student_mobile,
                }, "student_mobile")
              }
            />
            استفاده از شماره همراه ولی برای دانش‌آموز
          </label>
          </div>
          {mode === "edit" ? (
          <Field label="تلفن همراه ولی" error={errors.guardian_mobile}>
            <Input
              value={value.guardian_mobile}
              invalid={Boolean(errors.guardian_mobile)}
              onChange={(e) => patch({ guardian_mobile: e.target.value.replace(/\D/g, "").slice(0, 11) }, "guardian_mobile")}
              inputMode="tel"
              maxLength={11}
              dir="ltr"
              className="text-left"
            />
          </Field>
          ) : (
            <p className="text-xs text-[var(--muted)] md:col-span-2">
              شماره ولی در مرحله بعد، هنگام ثبت اولیا گرفته می‌شود.
            </p>
          )}
          <Field label="تلفن ثابت">
            <Input value={value.landline} onChange={(e) => patch({ landline: e.target.value })} dir="ltr" className="text-left" />
          </Field>
          <div className="md:col-span-2">
            <Field label="آدرس منزل">
              <Textarea rows={2} value={value.home_address} onChange={(e) => patch({ home_address: e.target.value })} />
            </Field>
          </div>
          <div className="md:col-span-2">
            <Field label="توضیحات">
              <Textarea rows={2} value={value.notes} onChange={(e) => patch({ notes: e.target.value })} />
            </Field>
          </div>
        </div>
        <FormErrorSummary errors={errors} general={generalError} />
        {actions ? <FormActions>{actions}</FormActions> : null}
      </div>
    </div>
  );
}

export function toStudentPayload(form: StudentFormValues) {
  return {
    first_name: form.first_name,
    last_name: form.last_name,
    national_code: form.national_code,
    is_foreign_national: form.is_foreign_national,
    gender: form.gender || null,
    birth_date: form.birth_date || null,
    birth_place: form.birth_place || null,
    branch_id: Number(form.branch_id),
    grade_level_id: form.grade_level_id ? Number(form.grade_level_id) : null,
    study_field_id: form.study_field_id ? Number(form.study_field_id) : null,
    academic_year_id: Number(form.academic_year_id),
    email: form.email || undefined,
    identity_data: {
      father_name: form.father_name,
      notes: form.notes,
    },
    contact_data: {
      guardian_mobile: form.guardian_mobile,
      landline: form.landline,
      student_mobile: form.student_uses_guardian_mobile ? "" : form.student_mobile,
      student_uses_guardian_mobile: form.student_uses_guardian_mobile,
      email: form.email,
      home_address: form.home_address,
    },
  };
}
