"use client";

import { useActionState, useEffect, useMemo, useState } from "react";
import { useFormStatus } from "react-dom";
import { useRouter } from "next/navigation";
import { CheckCircle2, ShieldAlert, TriangleAlert, UserPlus } from "lucide-react";
import { createStudentAction, type CreateStudentData } from "@/app/actions/students";
import type { ActionResult } from "@/app/actions/shared";
import { buttonClass, Callout, Field, inputClass, selectClass } from "@/components/ui";
import { useToast } from "@/components/toast";
import { normalizeStudentNumber, resolveCurriculumForStudentNumber } from "@/lib/curriculum-resolver";
import type { StudentNumberNormalization } from "@/lib/settings/constants";
import type { CurriculumAssignmentRule } from "@/types";

const initialState: ActionResult<CreateStudentData> = { ok: false, message: null };

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" className={buttonClass("primary")} disabled={pending}>
      <UserPlus className="h-4 w-4" aria-hidden />
      {pending ? "Creating…" : "Create student"}
    </button>
  );
}

/**
 * New student form with live curriculum detection.
 *
 * The preview runs the same pure resolver the server uses, so what the encoder
 * sees while typing matches exactly what will be stored — but the server still
 * re-resolves authoritatively on submit.
 */
export function NewStudentForm({
  curricula,
  rules,
  normalization,
  programs,
  scopedProgramId,
}: {
  curricula: { id: string; code: string; name: string }[];
  rules: CurriculumAssignmentRule[];
  normalization: StudentNumberNormalization;
  programs: { id: string; code: string; name: string }[];
  /** Non-null when the signed-in user is confined to one program. */
  scopedProgramId: string | null;
}) {
  const router = useRouter();
  const { toast } = useToast();
  const [state, formAction] = useActionState<ActionResult<CreateStudentData>, FormData>(
    createStudentAction,
    initialState,
  );
  const [studentNumber, setStudentNumber] = useState("");

  useEffect(() => {
    if (!state.message) return;
    toast({ tone: state.ok ? "success" : "error", title: state.message });
    if (state.ok && state.data) router.push(`/students/${state.data.studentId}/assessment`);
  }, [state, toast, router]);

  const preview = useMemo(() => {
    if (!studentNumber.trim()) return null;
    const normalized = normalizeStudentNumber(studentNumber, normalization);
    const resolution = resolveCurriculumForStudentNumber(studentNumber, rules, { normalization });
    const curriculum = resolution.curriculumId ? curricula.find((c) => c.id === resolution.curriculumId) : null;
    return { normalized, resolution, curriculum };
  }, [studentNumber, rules, curricula, normalization]);

  const error = (field: string) => state.fieldErrors?.[field] ?? null;

  return (
    <form action={formAction} className="space-y-6">
      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        <Field
          label="Student number"
          htmlFor="student_number"
          required
          error={error("student_number")}
          hint={preview ? `Stored key: ${preview.normalized}` : "Determines the curriculum automatically."}
        >
          <input
            id="student_number"
            name="student_number"
            value={studentNumber}
            onChange={(event) => setStudentNumber(event.target.value)}
            className={`${inputClass} tabular`}
            required
            maxLength={50}
            autoFocus
            placeholder="e.g. 2024-0001"
          />
        </Field>
        <Field label="Last name" htmlFor="last_name" required error={error("last_name")}>
          <input id="last_name" name="last_name" className={inputClass} required />
        </Field>
        <Field label="First name" htmlFor="first_name" required error={error("first_name")}>
          <input id="first_name" name="first_name" className={inputClass} required />
        </Field>
        <Field label="Middle name" htmlFor="middle_name" error={error("middle_name")}>
          <input id="middle_name" name="middle_name" className={inputClass} />
        </Field>
        <Field label="Suffix" htmlFor="suffix" error={error("suffix")}>
          <input id="suffix" name="suffix" className={inputClass} />
        </Field>

        {scopedProgramId ? (
          // A scoped user always creates inside their own program.
          <input type="hidden" name="program_id" value={scopedProgramId} />
        ) : (
          <Field
            label="Academic program"
            htmlFor="program_id"
            required
            error={error("program_id")}
            hint="Which college this student belongs to."
          >
            <select id="program_id" name="program_id" className={selectClass} required defaultValue={programs.length === 1 ? programs[0].id : ""}>
              <option value="">Select a program…</option>
              {programs.map((program) => (
                <option key={program.id} value={program.id}>
                  {program.code} — {program.name}
                </option>
              ))}
            </select>
          </Field>
        )}
      </div>

      {/* Live curriculum detection */}
      {preview ? (
        preview.resolution.outcome === "MATCHED" ? (
          <Callout tone="success">
            <span className="flex items-start gap-2">
              <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>
                Detected curriculum: <strong>{preview.curriculum?.code ?? "—"}</strong>
                {preview.curriculum ? ` — ${preview.curriculum.name}` : ""}
                <br />
                Matched rule: {preview.resolution.matchedRule?.name}
              </span>
            </span>
          </Callout>
        ) : preview.resolution.outcome === "CONFLICT" ? (
          <Callout tone="danger" title="CURRICULUM_RULE_CONFLICT">
            <span className="flex items-start gap-2">
              <ShieldAlert className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>
                {preview.resolution.message} The student will be created without a curriculum; an administrator must
                resolve the conflict.
              </span>
            </span>
          </Callout>
        ) : (
          <Callout tone="warning" title="CURRICULUM_UNRESOLVED">
            <span className="flex items-start gap-2">
              <TriangleAlert className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>
                No active assignment rule matches this student number. The student will be created without a
                curriculum, and an authorised user must assign one manually.
              </span>
            </span>
          </Callout>
        )
      ) : null}

      <div>
        <h3 className="mb-3 text-[11px] font-semibold uppercase tracking-wider text-ink-500">
          Pre-medical background (optional)
        </h3>
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          <Field label="Pre-med course" htmlFor="premed_course" error={error("premed_course")}>
            <input id="premed_course" name="premed_course" className={inputClass} placeholder="e.g. BS Biology" />
          </Field>
          <Field label="Pre-med school" htmlFor="premed_school" error={error("premed_school")}>
            <input id="premed_school" name="premed_school" className={inputClass} />
          </Field>
          <Field label="Year graduated" htmlFor="graduation_year" error={error("graduation_year")}>
            <input
              id="graduation_year"
              name="graduation_year"
              className={`${inputClass} tabular`}
              inputMode="numeric"
              placeholder="YYYY"
            />
          </Field>
          <Field label="GWA" htmlFor="gwa" error={error("gwa")}>
            <input id="gwa" name="gwa" className={`${inputClass} tabular`} />
          </Field>
          <Field label="NMAT score" htmlFor="nmat_score" error={error("nmat_score")}>
            <input id="nmat_score" name="nmat_score" className={`${inputClass} tabular`} inputMode="decimal" />
          </Field>
          <Field label="Year NMAT taken" htmlFor="nmat_year" error={error("nmat_year")}>
            <input
              id="nmat_year"
              name="nmat_year"
              className={`${inputClass} tabular`}
              inputMode="numeric"
              placeholder="YYYY"
            />
          </Field>
        </div>
      </div>

      <Field label="Notes" htmlFor="notes" error={error("notes")}>
        <textarea id="notes" name="notes" rows={3} className={inputClass} />
      </Field>

      <input type="hidden" name="active" value="true" />

      <div className="flex justify-end gap-2 border-t border-ink-200 pt-4">
        <SubmitButton />
      </div>
    </form>
  );
}
