"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import {
  GENDERS,
  INDIAN_STATES,
  STAY_TYPES,
  TRANSPORT_MODES,
} from "@/lib/constants";
import { formatAadhaarDisplay } from "@/lib/aadhaar-client";
import { EVENT } from "@/lib/event";
import { useHumanSignals } from "@/hooks/useHumanSignals";

type Step =
  | "consent"
  | "aadhaar"
  | "mobile"
  | "otp"
  | "profile"
  | "visit"
  | "review";

const STEPS: Step[] = [
  "consent",
  "aadhaar",
  "mobile",
  "otp",
  "profile",
  "visit",
  "review",
];

const STEP_LABELS: Record<Step, string> = {
  consent: "Consent",
  aadhaar: "Aadhaar",
  mobile: "Mobile",
  otp: "OTP",
  profile: "Profile",
  visit: "Visit details",
  review: "Review",
};

type FormState = {
  consent: boolean;
  aadhaar: string;
  mobile: string;
  otp: string;
  sessionId: string;
  token: string;
  name: string;
  age: string;
  gender: string;
  emergency: string;
  addressLine1: string;
  addressLine2: string;
  pincode: string;
  city: string;
  district: string;
  postOffice: string;
  state: string;
  arrival: string;
  transport: string;
  stay: string;
  devOtp?: string;
};

const initial: FormState = {
  consent: false,
  aadhaar: "",
  mobile: "",
  otp: "",
  sessionId: "",
  token: "",
  name: "",
  age: "",
  gender: "",
  emergency: "",
  addressLine1: "",
  addressLine2: "",
  pincode: "",
  city: "",
  district: "",
  postOffice: "",
  state: "Madhya Pradesh",
  arrival: "",
  transport: "",
  stay: "",
};

export function RegistrationWizard() {
  const router = useRouter();
  const { snapshot, setHoneypot } = useHumanSignals();
  const [step, setStep] = useState<Step>("consent");
  const [form, setForm] = useState<FormState>(initial);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const [declined, setDeclined] = useState(false);
  const [pinLooking, setPinLooking] = useState(false);
  const [pinHint, setPinHint] = useState("");
  const [offices, setOffices] = useState<string[]>([]);
  const [citySuggestions, setCitySuggestions] = useState<
    { city: string; state: string }[]
  >([]);
  const cityTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  const progress = useMemo(() => {
    const i = STEPS.indexOf(step);
    return ((i + 1) / STEPS.length) * 100;
  }, [step]);

  function update<K extends keyof FormState>(key: K, value: FormState[K]) {
    setForm((f) => ({ ...f, [key]: value }));
    setError("");
  }

  async function lookupPin(pin: string) {
    if (pin.length !== 6) {
      setPinHint("");
      setOffices([]);
      return;
    }
    setPinLooking(true);
    setPinHint("");
    try {
      const res = await fetch(`/api/v1/location/pincode/${pin}`);
      const data = await res.json();
      if (!data.ok) {
        setPinHint(data.error || "PIN not found — enter address manually.");
        setOffices([]);
        return;
      }
      setForm((f) => ({
        ...f,
        pincode: pin,
        state: data.state || f.state,
        district: data.district || f.district,
        postOffice: data.offices?.[0]?.office_name || f.postOffice,
        city: f.city || data.district || "",
      }));
      setOffices(
        (data.offices || []).map((o: { office_name: string }) => o.office_name),
      );
      setPinHint(`Found ${data.district}, ${data.state}`);
    } catch {
      setPinHint("Could not look up PIN. Enter address manually.");
    } finally {
      setPinLooking(false);
    }
  }

  function onCityType(value: string) {
    update("city", value);
    if (cityTimer.current) clearTimeout(cityTimer.current);
    if (value.trim().length < 2) {
      setCitySuggestions([]);
      return;
    }
    cityTimer.current = setTimeout(async () => {
      try {
        const params = new URLSearchParams({ q: value.trim() });
        if (form.state) params.set("state", form.state);
        const res = await fetch(`/api/v1/location/cities?${params}`);
        const data = await res.json();
        if (data.ok) setCitySuggestions(data.cities || []);
      } catch {
        setCitySuggestions([]);
      }
    }, 220);
  }

  useEffect(() => {
    return () => {
      if (cityTimer.current) clearTimeout(cityTimer.current);
    };
  }, []);

  async function validateAadhaar() {
    setLoading(true);
    setError("");
    try {
      const res = await fetch("/api/v1/registration/aadhaar/validate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          aadhaar_number: form.aadhaar,
          human: snapshot(),
        }),
      });
      const data = await res.json();
      if (!data.ok) {
        setError(data.error || "Invalid Aadhaar");
        if (data.pass_no) {
          setError(`${data.error} Pass: ${data.pass_no}`);
        }
        return;
      }
      setStep("mobile");
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setLoading(false);
    }
  }

  async function sendOtp() {
    setLoading(true);
    setError("");
    try {
      const res = await fetch("/api/v1/registration/otp/send", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          aadhaar_number: form.aadhaar,
          mobile: form.mobile,
          human: snapshot(),
        }),
      });
      const data = await res.json();
      if (!data.ok) {
        setError(data.error || "Could not send OTP");
        return;
      }
      update("sessionId", data.session_id);
      if (data.dev_otp) update("devOtp", data.dev_otp);
      setStep("otp");
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setLoading(false);
    }
  }

  async function verifyOtp() {
    setLoading(true);
    setError("");
    try {
      const res = await fetch("/api/v1/registration/otp/verify", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          session_id: form.sessionId,
          otp: form.otp,
          human: snapshot(),
        }),
      });
      const data = await res.json();
      if (!data.ok) {
        setError(data.error || "OTP verification failed");
        return;
      }
      update("token", data.token);
      try {
        sessionStorage.setItem(
          "kumbh_draft",
          JSON.stringify({
            name: form.name,
            age: form.age,
            gender: form.gender,
            state: form.state,
            arrival: form.arrival,
            transport: form.transport,
            stay: form.stay,
            emergency: form.emergency,
          }),
        );
      } catch {
        /* ignore */
      }
      setStep("profile");
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setLoading(false);
    }
  }

  async function submitRegistration() {
    setLoading(true);
    setError("");
    try {
      const res = await fetch("/api/v1/registration/visitors", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${form.token}`,
        },
        body: JSON.stringify({
          aadhaar_number: form.aadhaar.replace(/\s/g, ""),
          name: form.name,
          age: Number(form.age),
          gender: form.gender,
          mobile: form.mobile.replace(/\s/g, ""),
          emergency_contact: form.emergency.replace(/\s/g, ""),
          address_line1: form.addressLine1.trim(),
          address_line2: form.addressLine2.trim() || null,
          state: form.state,
          city: form.city.trim() || null,
          district: form.district.trim() || null,
          pincode: form.pincode || null,
          post_office: form.postOffice.trim() || null,
          arrival_date: form.arrival,
          transport_mode: form.transport,
          stay_type: form.stay,
          channel: "website",
          human: snapshot(),
        }),
      });
      const data = await res.json();
      if (!data.ok && !data.pass_no) {
        setError(data.error || "Registration failed");
        return;
      }
      const passNo = data.pass_no;
      try {
        sessionStorage.removeItem("kumbh_draft");
      } catch {
        /* ignore */
      }
      router.push(`/pass/${passNo}?new=1`);
    } catch {
      setError("Network error. Please try again.");
    } finally {
      setLoading(false);
    }
  }

  if (declined) {
    return (
      <div className="mx-auto max-w-lg rounded-2xl border border-[var(--line)] bg-[var(--bg-elevated)] p-8 text-center">
        <h2 className="font-display text-2xl font-semibold">Thank you</h2>
        <p className="mt-3 text-[var(--muted)]">
          No information was collected. You may register whenever you are ready.
        </p>
        <Link href="/" className="btn btn-primary mt-6">
          Return home
        </Link>
      </div>
    );
  }

  return (
    <div className="mx-auto w-full max-w-xl">
      <div className="mb-6">
        <div className="mb-2 flex items-center justify-between text-xs text-[var(--muted)]">
          <span>{STEP_LABELS[step]}</span>
          <span>
            Step {STEPS.indexOf(step) + 1} of {STEPS.length}
          </span>
        </div>
        <div className="progress-track">
          <div className="progress-fill" style={{ width: `${progress}%` }} />
        </div>
      </div>

      <div className="panel-surface relative rounded-2xl p-6 backdrop-blur-md md:p-8">
        <div
          aria-hidden="true"
          className="absolute -left-[9999px] h-px w-px overflow-hidden opacity-0"
        >
          <label htmlFor="company_website">Website</label>
          <input
            id="company_website"
            name="website"
            type="text"
            tabIndex={-1}
            autoComplete="off"
            onChange={(e) => setHoneypot(e.target.value)}
          />
        </div>

        {error && (
          <div className="alert alert-error mb-5" role="alert">
            {error}
          </div>
        )}

        {step === "consent" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Before you begin
            </h1>
            <p className="text-[var(--muted)]">
              We verify your identity with Aadhaar and mobile OTP, then issue a
              Kumbh Pass for Simhastha {EVENT.year} ({EVENT.dateRangeEn}). See
              our{" "}
              <a
                href="/privacy"
                className="text-[var(--gold)] underline-offset-2 hover:underline"
              >
                privacy policy
              </a>{" "}
              for how your data is handled.
            </p>
            <label className="flex cursor-pointer items-start gap-3 text-sm">
              <input
                type="checkbox"
                className="mt-1 accent-[var(--gold)]"
                checked={form.consent}
                onChange={(e) => update("consent", e.target.checked)}
              />
              <span>
                I understand the purpose of registration and consent to proceed.
              </span>
            </label>
            <div className="flex flex-wrap gap-3 pt-2">
              <button
                type="button"
                className="btn btn-primary"
                disabled={!form.consent}
                onClick={() => setStep("aadhaar")}
              >
                Continue
              </button>
              <button
                type="button"
                className="btn btn-secondary"
                onClick={() => setDeclined(true)}
              >
                Not now
              </button>
            </div>
          </div>
        )}

        {step === "aadhaar" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Enter Aadhaar
            </h1>
            <p className="text-sm text-[var(--muted)]">
              12-digit Aadhaar number. Spaces are allowed.
            </p>
            <div className="field">
              <label htmlFor="aadhaar">Aadhaar number</label>
              <input
                id="aadhaar"
                inputMode="numeric"
                autoComplete="off"
                placeholder="XXXX XXXX XXXX"
                value={formatAadhaarDisplay(form.aadhaar)}
                onChange={(e) =>
                  update("aadhaar", e.target.value.replace(/\D/g, "").slice(0, 12))
                }
              />
            </div>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={loading || form.aadhaar.length !== 12}
                onClick={validateAadhaar}
              >
                {loading ? "Checking…" : "Validate & continue"}
              </button>
              <button
                type="button"
                className="btn btn-ghost"
                onClick={() => setStep("consent")}
              >
                Back
              </button>
            </div>
          </div>
        )}

        {step === "mobile" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Mobile number
            </h1>
            <p className="text-sm text-[var(--muted)]">
              A six-digit OTP will be sent to this number for verification.
            </p>
            <div className="field">
              <label htmlFor="mobile">10-digit mobile</label>
              <input
                id="mobile"
                inputMode="numeric"
                placeholder="98XXXXXXXX"
                value={form.mobile}
                onChange={(e) =>
                  update("mobile", e.target.value.replace(/\D/g, "").slice(0, 10))
                }
              />
            </div>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={loading || form.mobile.length !== 10}
                onClick={sendOtp}
              >
                {loading ? "Sending…" : "Send OTP"}
              </button>
              <button
                type="button"
                className="btn btn-ghost"
                onClick={() => setStep("aadhaar")}
              >
                Back
              </button>
            </div>
          </div>
        )}

        {step === "otp" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Verify OTP
            </h1>
            <p className="text-sm text-[var(--muted)]">
              Enter the six-digit code sent to your mobile. Maximum 3 attempts.
            </p>
            {form.devOtp && (
              <div className="alert alert-info">
                Dev mode OTP: <strong>{form.devOtp}</strong>
              </div>
            )}
            <div className="field">
              <label htmlFor="otp">OTP</label>
              <input
                id="otp"
                inputMode="numeric"
                placeholder="••••••"
                value={form.otp}
                onChange={(e) =>
                  update("otp", e.target.value.replace(/\D/g, "").slice(0, 6))
                }
              />
            </div>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={loading || form.otp.length !== 6}
                onClick={verifyOtp}
              >
                {loading ? "Verifying…" : "Verify"}
              </button>
              <button
                type="button"
                className="btn btn-secondary"
                disabled={loading}
                onClick={sendOtp}
              >
                Resend OTP
              </button>
              <button
                type="button"
                className="btn btn-ghost"
                onClick={() => setStep("mobile")}
              >
                Back
              </button>
            </div>
          </div>
        )}

        {step === "profile" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">Your details</h1>
            <p className="text-sm text-[var(--muted)]">
              Enter your name as on Aadhaar (eKYC will prefill this when
              integrated).
            </p>
            <div className="field">
              <label htmlFor="name">Full name</label>
              <input
                id="name"
                value={form.name}
                onChange={(e) => update("name", e.target.value)}
                placeholder="Rajesh Kumar"
              />
            </div>
            <div className="grid grid-cols-2 gap-3">
              <div className="field">
                <label htmlFor="age">Age</label>
                <input
                  id="age"
                  inputMode="numeric"
                  value={form.age}
                  onChange={(e) =>
                    update("age", e.target.value.replace(/\D/g, "").slice(0, 3))
                  }
                  placeholder="34"
                />
              </div>
              <div className="field">
                <label htmlFor="gender">Gender</label>
                <select
                  id="gender"
                  value={form.gender}
                  onChange={(e) => update("gender", e.target.value)}
                >
                  <option value="">Select</option>
                  {GENDERS.map((g) => (
                    <option key={g} value={g}>
                      {g}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={
                  !form.name.trim() ||
                  !form.age ||
                  Number(form.age) < 1 ||
                  !form.gender
                }
                onClick={() => setStep("visit")}
              >
                Continue
              </button>
            </div>
          </div>
        )}

        {step === "visit" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Visit details
            </h1>
            <div className="field">
              <label htmlFor="emergency">Emergency contact</label>
              <input
                id="emergency"
                inputMode="numeric"
                value={form.emergency}
                onChange={(e) =>
                  update(
                    "emergency",
                    e.target.value.replace(/\D/g, "").slice(0, 10),
                  )
                }
                placeholder="97XXXXXXXX"
              />
            </div>

            <div className="rounded-xl border border-[var(--line)] bg-[rgba(61,95,143,0.06)] p-4">
              <p className="mb-3 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--neela)]">
                Home address — for emergency coordination
              </p>
              <p className="mb-3 text-xs text-[var(--muted)]">
                Used only if authorities need to reach your registered home during
                the event.
              </p>
              <div className="grid gap-3 sm:grid-cols-2">
                <div className="field sm:col-span-2">
                  <label htmlFor="address1">Address line 1</label>
                  <input
                    id="address1"
                    value={form.addressLine1}
                    onChange={(e) => update("addressLine1", e.target.value)}
                    placeholder="House / flat no., street, landmark"
                    maxLength={200}
                    required
                  />
                </div>
                <div className="field sm:col-span-2">
                  <label htmlFor="address2">Address line 2 (optional)</label>
                  <input
                    id="address2"
                    value={form.addressLine2}
                    onChange={(e) => update("addressLine2", e.target.value)}
                    placeholder="Area, colony, village"
                    maxLength={200}
                  />
                </div>
                <div className="field">
                  <label htmlFor="pincode">PIN code</label>
                  <input
                    id="pincode"
                    inputMode="numeric"
                    placeholder="452001"
                    value={form.pincode}
                    onChange={(e) => {
                      const pin = e.target.value.replace(/\D/g, "").slice(0, 6);
                      update("pincode", pin);
                      if (pin.length === 6) void lookupPin(pin);
                    }}
                  />
                  <p className="text-xs text-[var(--muted)]">
                    {pinLooking
                      ? "Looking up PIN…"
                      : pinHint || "6-digit India Post PIN"}
                  </p>
                </div>
                <div className="field">
                  <label htmlFor="state">State</label>
                  <select
                    id="state"
                    value={form.state}
                    onChange={(e) => update("state", e.target.value)}
                  >
                    {INDIAN_STATES.map((s) => (
                      <option key={s} value={s}>
                        {s}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="field">
                  <label htmlFor="district">District</label>
                  <input
                    id="district"
                    value={form.district}
                    onChange={(e) => update("district", e.target.value)}
                    placeholder="Indore"
                  />
                </div>
                <div className="field relative">
                  <label htmlFor="city">City / town</label>
                  <input
                    id="city"
                    value={form.city}
                    onChange={(e) => onCityType(e.target.value)}
                    onBlur={() => {
                      setTimeout(() => setCitySuggestions([]), 150);
                    }}
                    placeholder="Start typing city name"
                    autoComplete="off"
                  />
                  {citySuggestions.length > 0 ? (
                    <ul className="absolute left-0 right-0 top-full z-20 mt-1 max-h-48 overflow-auto rounded-xl border border-[var(--line)] bg-[var(--bg-elevated)] shadow-lg">
                      {citySuggestions.map((c) => (
                        <li key={`${c.city}-${c.state}`}>
                          <button
                            type="button"
                            className="block w-full px-3 py-2 text-left text-sm hover:bg-[var(--gold-soft)]"
                            onMouseDown={(e) => e.preventDefault()}
                            onClick={() => {
                              setForm((f) => ({
                                ...f,
                                city: c.city,
                                state: c.state,
                              }));
                              setCitySuggestions([]);
                            }}
                          >
                            <span className="font-medium">{c.city}</span>
                            <span className="text-[var(--muted)]">
                              {" "}
                              · {c.state}
                            </span>
                          </button>
                        </li>
                      ))}
                    </ul>
                  ) : null}
                </div>
                {offices.length > 0 ? (
                  <div className="field sm:col-span-2">
                    <label htmlFor="postOffice">Post office</label>
                    <select
                      id="postOffice"
                      value={form.postOffice}
                      onChange={(e) => update("postOffice", e.target.value)}
                    >
                      {offices.map((o) => (
                        <option key={o} value={o}>
                          {o}
                        </option>
                      ))}
                    </select>
                  </div>
                ) : (
                  <div className="field sm:col-span-2">
                    <label htmlFor="postOffice">Post office (optional)</label>
                    <input
                      id="postOffice"
                      value={form.postOffice}
                      onChange={(e) => update("postOffice", e.target.value)}
                      placeholder="Local post office"
                    />
                  </div>
                )}
              </div>
            </div>

            <div className="field">
              <label htmlFor="arrival">Arrival date (during Simhastha)</label>
              <input
                id="arrival"
                type="date"
                value={form.arrival}
                min={EVENT.startDate}
                max={EVENT.endDate}
                onChange={(e) => update("arrival", e.target.value)}
              />
              <p className="text-xs text-[var(--muted)]">
                Event dates: {EVENT.dateRangeEn}
              </p>
            </div>
            <div>
              <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-[var(--muted)]">
                Transport mode
              </p>
              <div className="choice-grid">
                {TRANSPORT_MODES.map((t) => (
                  <button
                    key={t}
                    type="button"
                    className="choice"
                    aria-pressed={form.transport === t}
                    onClick={() => update("transport", t)}
                  >
                    {t}
                  </button>
                ))}
              </div>
            </div>
            <div>
              <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-[var(--muted)]">
                Stay type
              </p>
              <div className="choice-grid">
                {STAY_TYPES.map((t) => (
                  <button
                    key={t}
                    type="button"
                    className="choice"
                    aria-pressed={form.stay === t}
                    onClick={() => update("stay", t)}
                  >
                    {t}
                  </button>
                ))}
              </div>
            </div>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={
                  form.emergency.length !== 10 ||
                  !form.addressLine1.trim() ||
                  !form.state ||
                  !form.city.trim() ||
                  !form.arrival ||
                  !form.transport ||
                  !form.stay
                }
                onClick={() => {
                  if (form.emergency === form.mobile) {
                    setError(
                      "Emergency contact cannot match your primary mobile number.",
                    );
                    return;
                  }
                  setStep("review");
                }}
              >
                Review
              </button>
              <button
                type="button"
                className="btn btn-ghost"
                onClick={() => setStep("profile")}
              >
                Back
              </button>
            </div>
          </div>
        )}

        {step === "review" && (
          <div className="space-y-5">
            <h1 className="font-display text-3xl font-semibold">
              Confirm details
            </h1>
            <dl className="space-y-3 text-sm">
              {[
                ["Name", form.name],
                ["Mobile", `${form.mobile.slice(0, 2)}XXXXXX${form.mobile.slice(-2)}`],
                [
                  "Home",
                  [
                    form.addressLine1,
                    form.addressLine2,
                    form.city,
                    form.district,
                    form.state,
                    form.pincode,
                  ]
                    .filter(Boolean)
                    .join(", "),
                ],
                ["Arrival", form.arrival],
                ["Travel", form.transport],
                ["Stay", form.stay],
              ].map(([k, v]) => (
                <div
                  key={k}
                  className="flex items-baseline justify-between gap-4 border-b border-[var(--line)] pb-2"
                >
                  <dt className="text-[var(--muted)]">{k}</dt>
                  <dd className="font-medium">{v}</dd>
                </div>
              ))}
            </dl>
            <div className="flex flex-wrap gap-3">
              <button
                type="button"
                className="btn btn-primary"
                disabled={loading}
                onClick={submitRegistration}
              >
                {loading ? "Submitting…" : "Confirm & Register"}
              </button>
              <button
                type="button"
                className="btn btn-ghost"
                onClick={() => setStep("visit")}
              >
                Edit
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
