"use client";

import { useEffect, useRef, useState, type CSSProperties, type ReactNode } from "react";
import { useLang } from "@/context/LanguageContext";
import { Alert, Button, DatePicker, Input, Select, Textarea } from "@/components/ui";
import { BLOOD_GROUPS } from "@/lib/constants";
import { IconArrowRight, IconCheck } from "@/components/icons";

/* Shared admission application wizard — the public /apply page and the
   portal Admission Form render the same steps, validation and review so the
   two stay one experience:
   Student → Guardian & Contact → Address & Note → Review.

   The step index is controlled by the parent (the public page counts the
   Institution lookup as its own step 0). Title, stepper and nav stay
   visible while only the step body scrolls (ems-wizard-scroll). */

export interface AdmissionFormValues {
  studentName: string;
  studentNameBn: string;
  classItemId: string;
  sessionItemId: string;
  gender: string;
  dob: string;
  bloodGroup: string;
  religion: string;
  guardianName: string;
  guardianNameBn: string;
  guardianPhone: string;
  motherName: string;
  motherNameBn: string;
  studentPhone: string;
  email: string;
  address: string;
  permanentAddress: string;
  note: string;
}

export const emptyAdmissionForm: AdmissionFormValues = {
  studentName: "",
  studentNameBn: "",
  classItemId: "",
  sessionItemId: "",
  gender: "MALE",
  dob: "",
  bloodGroup: "",
  religion: "",
  guardianName: "",
  guardianNameBn: "",
  guardianPhone: "",
  motherName: "",
  motherNameBn: "",
  studentPhone: "",
  email: "",
  address: "",
  permanentAddress: "",
  note: "",
};

/** contact numbers are stored as digits only */
const digitsOnly = (v: string) => v.replace(/\D/g, "");
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export const WIZARD_LAST_STEP = 3; // 0 student · 1 guardian · 2 address · 3 review

const RELIGIONS = ["ISLAM", "HINDUISM", "CHRISTIANITY", "BUDDHISM", "OTHER"] as const;

const DOT: CSSProperties = {
  width: 34, height: 34, borderRadius: "50%",
  display: "flex", alignItems: "center", justifyContent: "center",
  fontSize: 13, fontWeight: 700, flexShrink: 0, transition: "all .15s ease",
};
const DOT_TODO: CSSProperties = { background: "#f1f4f3", color: "#8a9691", border: "1px solid #e2e8e6" };
const DOT_ACTIVE: CSSProperties = { background: "#24695c", color: "#fff", boxShadow: "0 0 0 4px rgba(36,105,92,0.15)" };
const DOT_DONE: CSSProperties = { background: "#5ec8b4", color: "#fff" };

/** horizontal wizard stepper — completed steps are clickable to go back.
    On narrow screens only the dots show (labels hide below md) and a compact
    "Step n of m — label" line appears instead. */
export function AdmissionStepper({
  steps,
  current,
  onJump,
  stepOf,
}: {
  steps: string[];
  current: number;
  onJump: (i: number) => void;
  stepOf: string;
}) {
  return (
    <div className="mb-4">
      <div className="d-flex align-items-start px-2 px-md-0">
        {steps.map((label, i) => {
          const state = i < current ? "done" : i === current ? "active" : "todo";
          return (
            <div
              key={label}
              className="d-flex align-items-start"
              style={{ flex: i === steps.length - 1 ? "0 0 auto" : "1 1 auto" }}
            >
              <button
                type="button"
                className="d-flex flex-column align-items-center bg-transparent border-0 p-0"
                style={{ cursor: i < current ? "pointer" : "default" }}
                disabled={i >= current}
                onClick={() => i < current && onJump(i)}
                tabIndex={i < current ? 0 : -1}
              >
                <span style={{ ...DOT, ...(state === "done" ? DOT_DONE : state === "active" ? DOT_ACTIVE : DOT_TODO) }}>
                  {state === "done" ? <IconCheck className="svg-14" /> : i + 1}
                </span>
                <span
                  className={`ems-fs-11 mt-1 text-nowrap d-none d-md-block ${state === "active" ? "f-w-700 ems-text-teal" : state === "done" ? "f-w-600 text-dark" : "text-muted"}`}
                >
                  {label}
                </span>
              </button>
              {i < steps.length - 1 && (
                <div
                  aria-hidden
                  style={{ flex: 1, height: 2, margin: "16px 6px 0", background: i < current ? "#5ec8b4" : "#e6edef" }}
                />
              )}
            </div>
          );
        })}
      </div>
      {/* compact caption for narrow screens */}
      <p className="d-md-none ems-fs-12 f-w-700 ems-text-teal text-center mt-2 mb-0">
        {stepOf.replace("{n}", String(current + 1)).replace("{m}", String(steps.length))} — {steps[current]}
      </p>
    </div>
  );
}

/** boxed form section mirroring the admission form layout */
export function WizardFormSection({ title, children }: { title: string; children: ReactNode }) {
  return (
    <div className="mb-2" style={{ border: "1px solid #e6edef", borderRadius: 10, padding: "10px 12px 0" }}>
      <p className="f-w-700 ems-fs-13 mb-2 ems-text-teal">{title}</p>
      {children}
    </div>
  );
}

/** review row: label + value (— when empty) */
export function WizardReviewRow({ label, value }: { label: string; value?: ReactNode }) {
  const empty = value === undefined || value === null || String(value).trim() === "";
  return (
    <div className="d-flex justify-content-between gap-3 py-1" style={{ borderBottom: "1px dashed #edf2f0" }}>
      <span className="ems-fs-12 text-muted text-nowrap">{label}</span>
      <span className={`ems-fs-13 text-end ${empty ? "text-muted" : "f-w-600"}`}>{empty ? "—" : value}</span>
    </div>
  );
}

export function AdmissionFormWizard({
  classes,
  sessions,
  values,
  onChange,
  step,
  onStep,
  submitLabel,
  submitting = false,
  onSubmit,
  onBackFirst,
  onCancel,
  above,
  reviewTop,
  honeypot,
  hideStepper = false,
  extraStep2,
}: {
  classes: { id: number; name: string; nameBn: string }[];
  sessions?: { id: number; name: string; nameBn: string }[];
  values: AdmissionFormValues;
  onChange: (values: AdmissionFormValues) => void;
  /** 0 student · 1 guardian · 2 address · 3 review (controlled) */
  step: number;
  onStep: (step: number) => void;
  submitLabel: string;
  submitting?: boolean;
  onSubmit: () => void;
  /** Back on the first step (public page: back to institution lookup) */
  onBackFirst?: () => void;
  /** optional Cancel button shown next to Back (portal modal) */
  onCancel?: () => void;
  /** rendered above the steps inside the scroll area (banner / fee notice) */
  above?: ReactNode;
  /** extra rows at the top of the review step (institution + fee on /apply) */
  reviewTop?: ReactNode;
  /** public anti-spam honeypot field */
  honeypot?: { value: string; setValue: (v: string) => void };
  hideStepper?: boolean;
  /** extra block at the end of the Address & Note step (public: tracking account) */
  extraStep2?: ReactNode;
}) {
  const { t, locale } = useLang();
  const f = t.portal.admissionsPage;
  const a = t.applyPage;

  const [stepError, setStepError] = useState("");
  const scrollRef = useRef<HTMLDivElement>(null);

  const stepLabels = [a.stepStudent, a.stepGuardian, a.stepAddress, a.stepReview];

  // a fresh step always starts scrolled to its top
  useEffect(() => {
    scrollRef.current?.scrollTo({ top: 0 });
  }, [step]);

  const selectedClass = classes.find((c) => String(c.id) === values.classItemId);
  const selectedSession = sessions?.find((s) => String(s.id) === values.sessionItemId);
  const set = (patch: Partial<AdmissionFormValues>) => onChange({ ...values, ...patch });

  /** per-step required-field check guarding the Continue button */
  function stepValid(i: number): boolean {
    if (i === 0) return values.studentName.trim().length > 0;
    if (i === 1) {
      if (values.guardianPhone.trim().length === 0) return false;
      // a filled email must be a valid address
      if (values.email.trim() && !EMAIL_RE.test(values.email.trim())) return false;
    }
    return true;
  }

  /** the specific message for the current step's validation failure */
  function stepErrorMessage(): string | null {
    if (step === 1) {
      if (values.email.trim() && !EMAIL_RE.test(values.email.trim())) {
        return t.common.invalidEmail;
      }
      if (values.guardianPhone.trim().length === 0) return a.stepInvalid;
    }
    if (step === 0 && values.studentName.trim().length === 0) return a.stepInvalid;
    return null;
  }

  function goToStep(i: number) {
    setStepError("");
    onStep(i);
  }

  function nextStep() {
    if (!stepValid(step)) {
      setStepError(stepErrorMessage() ?? a.stepInvalid);
      return;
    }
    goToStep(Math.min(step + 1, WIZARD_LAST_STEP));
  }

  /** Enter inside any input advances the wizard; only the review step submits */
  function onFormSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (step < WIZARD_LAST_STEP) {
      nextStep();
      return;
    }
    if (stepValid(0) && stepValid(1)) onSubmit();
  }

  const genderLabel =
    values.gender === "FEMALE" ? f.female : values.gender === "OTHER" ? f.other : f.male;
  const religionLabel = (r: string) =>
    r === "ISLAM" ? f.islam
      : r === "HINDUISM" ? f.hinduism
      : r === "CHRISTIANITY" ? f.christianity
      : r === "BUDDHISM" ? f.buddhism
      : f.otherReligion;

  return (
    <div className="d-flex flex-column" style={{ flex: "1 1 auto", minHeight: 0 }}>
      {!hideStepper && <AdmissionStepper steps={stepLabels} current={step} onJump={goToStep} stepOf={a.stepOf} />}

      <div className="ems-wizard-scroll" ref={scrollRef}>
        {above}

        <form className="theme-form" onSubmit={onFormSubmit}>
          {/* hidden submit button keeps Enter-key submission alive on every
              step (browsers block implicit submit without one) */}
          <button type="submit" className="d-none" aria-hidden="true" tabIndex={-1} />
          {/* honeypot — invisible to humans */}
          {honeypot && (
            <input
              type="text"
              name="company"
              value={honeypot.value}
              tabIndex={-1}
              autoComplete="off"
              aria-hidden="true"
              style={{ position: "absolute", left: -5000, opacity: 0 }}
              onChange={(e) => honeypot.setValue(e.target.value)}
            />
          )}

          {step === 0 && (
            /* ---------- Student ---------- */
            <div>
              <WizardFormSection title={f.sectionAdmissionInfo}>
                <div className="row g-2">
                  <div className="col-12 col-md-6">
                    <Input
                      label={`${f.studentName} *`}
                      value={values.studentName}
                      onChange={(e) => set({ studentName: e.target.value })}
                    />
                  </div>
                  <div className="col-12 col-md-6">
                    <Input
                      label={f.studentNameBn}
                      value={values.studentNameBn}
                      placeholder="বাংলায়"
                      onChange={(e) => set({ studentNameBn: e.target.value })}
                    />
                  </div>
                  <div className="col-12 col-md-6">
                    <Select
                      label={f.applyClass}
                      value={values.classItemId}
                      onChange={(e) => set({ classItemId: e.target.value })}
                    >
                      <option value="">—</option>
                      {classes.map((c) => (
                        <option key={c.id} value={c.id}>
                          {locale === "bn" ? c.nameBn : c.name}
                        </option>
                      ))}
                    </Select>
                  </div>
                  <div className="col-12 col-md-6">
                    <Select
                      label={t.categories.SESSION}
                      value={values.sessionItemId}
                      onChange={(e) => set({ sessionItemId: e.target.value })}
                    >
                      <option value="">—</option>
                      {(sessions ?? []).map((s) => (
                        <option key={s.id} value={s.id}>
                          {locale === "bn" ? s.nameBn : s.name}
                        </option>
                      ))}
                    </Select>
                  </div>
                </div>
              </WizardFormSection>

              <WizardFormSection title={f.sectionIdentity}>
                <div className="row g-2">
                  <div className="col-12 col-md-6">
                    <Select label={f.gender} value={values.gender} onChange={(e) => set({ gender: e.target.value })}>
                      <option value="MALE">{f.male}</option>
                      <option value="FEMALE">{f.female}</option>
                      <option value="OTHER">{f.other}</option>
                    </Select>
                  </div>
                  <div className="col-12 col-md-6">
                    <DatePicker label={f.dob} value={values.dob} onChange={(e) => set({ dob: e.target.value })} />
                  </div>
                  <div className="col-12 col-md-6">
                    <Select label={f.bloodGroup} value={values.bloodGroup} onChange={(e) => set({ bloodGroup: e.target.value })}>
                      <option value="">—</option>
                      {BLOOD_GROUPS.map((b) => (
                        <option key={b} value={b}>{b}</option>
                      ))}
                    </Select>
                  </div>
                  <div className="col-12 col-md-6">
                    <Select label={f.religion} value={values.religion} onChange={(e) => set({ religion: e.target.value })}>
                      <option value="">—</option>
                      {RELIGIONS.map((r) => (
                        <option key={r} value={r}>{religionLabel(r)}</option>
                      ))}
                    </Select>
                  </div>
                </div>
              </WizardFormSection>
            </div>
          )}

          {step === 1 && (
            /* ---------- Guardian & contact ---------- */
            <WizardFormSection title={f.sectionContact}>
              <div className="row g-2">
                <div className="col-12 col-md-6">
                  <Input label={f.guardianName} value={values.guardianName} onChange={(e) => set({ guardianName: e.target.value })} />
                </div>
                <div className="col-12 col-md-6">
                  <Input
                    label={f.guardianNameBn ?? f.guardianName}
                    value={values.guardianNameBn}
                    placeholder="বাংলায়"
                    onChange={(e) => set({ guardianNameBn: e.target.value })}
                  />
                </div>
                <div className="col-12 col-md-6">
                  <Input label={f.motherName ?? t.portal.studentsPage.motherName} value={values.motherName} onChange={(e) => set({ motherName: e.target.value })} />
                </div>
                <div className="col-12 col-md-6">
                  <Input
                    label={f.motherNameBn ?? t.portal.studentsPage.motherName}
                    value={values.motherNameBn}
                    placeholder="বাংলায়"
                    onChange={(e) => set({ motherNameBn: e.target.value })}
                  />
                </div>
                <div className="col-12 col-md-6">
                  <Input
                    label={`${f.guardianPhone} *`}
                    placeholder="01XXXXXXXXX"
                    inputMode="numeric"
                    value={values.guardianPhone}
                    onChange={(e) => set({ guardianPhone: digitsOnly(e.target.value) })}
                  />
                </div>
                <div className="col-12 col-md-6">
                  <Input
                    label={f.studentPhone}
                    placeholder="01XXXXXXXXX"
                    inputMode="numeric"
                    value={values.studentPhone}
                    onChange={(e) => set({ studentPhone: digitsOnly(e.target.value) })}
                  />
                </div>
                <div className="col-12 col-md-6">
                  <Input
                    label={t.common.email}
                    type="email"
                    value={values.email}
                    onChange={(e) => set({ email: e.target.value })}
                  />
                </div>
              </div>
            </WizardFormSection>
          )}

          {step === 2 && (
            /* ---------- Address & note ---------- */
            <div>
              <WizardFormSection title={f.sectionAddress}>
                <div className="row g-2">
                  <div className="col-12 col-md-6">
                    <Textarea label={f.presentAddress} value={values.address} onChange={(e) => set({ address: e.target.value })} />
                  </div>
                  <div className="col-12 col-md-6">
                    <Textarea label={f.permanentAddress} value={values.permanentAddress} onChange={(e) => set({ permanentAddress: e.target.value })} />
                  </div>
                </div>
              </WizardFormSection>

              <Textarea
                label={f.note}
                value={values.note}
                placeholder={f.notePlaceholder}
                onChange={(e) => set({ note: e.target.value })}
              />

              {extraStep2}
            </div>
          )}

          {step === 3 && (
            /* ---------- Review & submit ---------- */
            <div>
              <p className="f-w-700 ems-fs-13 ems-text-teal mb-1">{a.reviewTitle}</p>
              <p className="ems-fs-12 text-muted">{a.reviewHint}</p>

              {reviewTop}

              <WizardFormSection title={a.stepStudent}>
                <WizardReviewRow label={f.studentName} value={values.studentName} />
                <WizardReviewRow label={f.studentNameBn} value={values.studentNameBn} />
                <WizardReviewRow label={f.applyClass} value={selectedClass ? (locale === "bn" ? selectedClass.nameBn : selectedClass.name) : ""} />
                <WizardReviewRow
                  label={t.categories.SESSION}
                  value={selectedSession ? (locale === "bn" ? selectedSession.nameBn : selectedSession.name) : ""}
                />
                <WizardReviewRow label={f.gender} value={genderLabel} />
                <WizardReviewRow label={f.dob} value={values.dob} />
                <WizardReviewRow label={f.bloodGroup} value={values.bloodGroup} />
                <WizardReviewRow label={f.religion} value={values.religion ? religionLabel(values.religion) : ""} />
              </WizardFormSection>

              <WizardFormSection title={a.stepGuardian}>
                <WizardReviewRow label={f.guardianName} value={values.guardianName} />
                <WizardReviewRow label={f.guardianNameBn ?? f.guardianName} value={values.guardianNameBn} />
                <WizardReviewRow label={f.motherName ?? t.portal.studentsPage.motherName} value={values.motherName} />
                <WizardReviewRow label={f.guardianPhone} value={values.guardianPhone} />
                <WizardReviewRow label={f.studentPhone} value={values.studentPhone} />
                <WizardReviewRow label={t.common.email} value={values.email} />
              </WizardFormSection>

              <WizardFormSection title={a.stepAddress}>
                <WizardReviewRow label={f.presentAddress} value={values.address} />
                <WizardReviewRow label={f.permanentAddress} value={values.permanentAddress} />
                <WizardReviewRow label={f.note} value={values.note} />
              </WizardFormSection>
            </div>
          )}
        </form>
      </div>

      {stepError && (
        <div className="pt-2">
          <Alert type="error">{stepError}</Alert>
        </div>
      )}

      {/* wizard navigation — always visible below the scrolling step body */}
      <div className="d-flex justify-content-between align-items-center gap-2 pt-3 flex-wrap">
        <div className="d-flex gap-2">
          {step > 0 ? (
            <Button type="button" variant="secondary" onClick={() => goToStep(step - 1)}>
              {a.backButton}
            </Button>
          ) : (
            onBackFirst && (
              <Button type="button" variant="secondary" onClick={onBackFirst}>
                {a.backButton}
              </Button>
            )
          )}
          {onCancel && (
            <Button type="button" variant="secondary" onClick={onCancel}>
              {t.common.cancel}
            </Button>
          )}
        </div>
        {step < WIZARD_LAST_STEP ? (
          <Button type="button" onClick={nextStep} disabled={!stepValid(step)}>
            {a.continueButton}
            <IconArrowRight className="svg-16 ms-1" />
          </Button>
        ) : (
          <Button
            type="button"
            size="lg"
            loading={submitting}
            disabled={!stepValid(0) || !stepValid(1)}
            onClick={onSubmit}
          >
            {submitLabel}
            <IconArrowRight className="svg-16 ms-1" />
          </Button>
        )}
      </div>
    </div>
  );
}
