import { Link, useNavigate } from "@tanstack/react-router";
import { useEffect, useRef, useState } from "react";
import { ArrowRight, ArrowLeft, Loader2 } from "lucide-react";
import { supabase } from "@/integrations/supabase/client";
import { requestPartnerOtp, verifyPartnerOtp } from "@/lib/partner-auth.functions";

export function PartnerLoginCard({
  className = "",
  initialStep = 0,
}: {
  className?: string;
  initialStep?: 0 | 1 | 2;
}) {
  const navigate = useNavigate();
  const [step, setStep] = useState<0 | 1 | 2>(initialStep);
  const [mobile, setMobile] = useState("");
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [otp, setOtp] = useState(["", "", "", ""]);
  const [seconds, setSeconds] = useState(0);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [preview, setPreview] = useState("");

  const inputs = useRef<Array<HTMLInputElement | null>>([]);
  const mobileInput = useRef<HTMLInputElement | null>(null);

  // Sync whatever is physically in the field (covers browser/extension
  // autofill that bypasses React events) before validating.
  function submitMobile() {
    const dom = mobileInput.current?.value.replace(/\D/g, "").slice(0, 10) ?? "";
    if (dom !== mobile) setMobile(dom);
    if (!/^[6-9]\d{9}$/.test(dom)) {
      setError("Enter a valid 10-digit mobile number.");
      return;
    }
    void sendCode(dom);
  }

  useEffect(() => {
    if (seconds <= 0) return;
    const t = setTimeout(() => setSeconds((s) => s - 1), 1000);
    return () => clearTimeout(t);
  }, [seconds]);

  const digits = mobile.replace(/\D/g, "").slice(-10);
  const code = otp.join("");

  function withTimeout<T>(p: Promise<T>, ms = 20000): Promise<T> {
    return Promise.race([
      p,
      new Promise<T>((_, reject) =>
        setTimeout(() => reject(new Error("This is taking too long — please try again.")), ms),
      ),
    ]);
  }

  async function sendCode(phoneOverride?: string) {
    const phone = phoneOverride ?? digits;
    if (busy) return;
    if (!/^[6-9]\d{9}$/.test(phone)) {
      setError("Enter a valid 10-digit mobile number.");
      return;
    }
    setBusy(true);
    setError("");
    try {
      const res = await withTimeout(requestPartnerOtp({ data: { phone } }));
      setPreview(res.previewCode);
      setStep(1);
      setSeconds(30);
      setOtp(["", "", "", ""]);
      setTimeout(() => inputs.current[0]?.focus(), 60);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Could not send the code");
    } finally {
      setBusy(false);
    }
  }

  async function verify() {
    if (code.length !== 4 || busy) return;
    setBusy(true);
    setError("");
    try {
      const res = await withTimeout(verifyPartnerOtp({ data: { phone: digits, code } }));
      if (!res.ok) {
        setError(res.message);
        setOtp(["", "", "", ""]);
        setTimeout(() => inputs.current[0]?.focus(), 60);
        setBusy(false);
        return;
      }
      const { error: sessionError } = await supabase.auth.setSession({
        access_token: res.accessToken,
        refresh_token: res.refreshToken,
      });
      if (sessionError) throw new Error(sessionError.message);
      // Always land on the business chooser; it forwards to registration only
      // when the account has no business yet.
      navigate({ to: "/select-user", replace: true });
    } catch (e) {
      setError(e instanceof Error ? e.message : "Could not verify the code");
      setBusy(false);
    }
  }

  function submitSignup() {
    const phone = mobile.replace(/\D/g, "").slice(0, 10);
    if (!/^[6-9]\d{9}$/.test(phone)) {
      setError("Enter a valid 10-digit mobile number.");
      return;
    }
    if (name.trim().length < 2) {
      setError("Enter your name.");
      return;
    }
    if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
      setError("Enter a valid email address.");
      return;
    }
    try {
      sessionStorage.setItem(
        "airfis_signup",
        JSON.stringify({ phone, name: name.trim(), email: email.trim() }),
      );
    } catch {
      // storage unavailable — signup still proceeds
    }
    void sendCode(phone);
  }

  function setDigit(i: number, value: string) {
    const v = value.replace(/\D/g, "").slice(-1);
    setOtp((prev) => {
      const next = [...prev];
      next[i] = v;
      return next;
    });
    if (v && i < 3) inputs.current[i + 1]?.focus();
  }

  return (
    <div className={`bg-white p-6 sm:p-8 ${className}`}>
      {step === 0 ? (
        <>
          <h2 className="text-[28px] font-semibold leading-tight text-gray-950">Login</h2>
          <p className="mt-2 text-sm font-medium text-gray-950">
            or{" "}
            <button
              type="button"
              onClick={() => {
                setStep(2);
                setError("");
              }}
              className="font-semibold text-[#FF4308] hover:underline"
            >
              create an account
            </button>
          </p>
          <span className="mt-5 block h-0.5 w-8 bg-gray-950" aria-hidden />

          <div className="mt-5 rounded-xl border border-gray-300 px-4 py-3 focus-within:border-gray-950 transition-colors">
            <label htmlFor="partner-mobile" className="block text-xs font-medium text-gray-500">
              Phone number
            </label>
            <div className="mt-1 flex items-center gap-2 text-sm">
              <span className="shrink-0 text-gray-500">+91</span>
              <input
                id="partner-mobile"
                ref={mobileInput}
                inputMode="numeric"
                autoComplete="tel"
                value={mobile}
                placeholder="98765 43210"
                onChange={(e) => setMobile(e.target.value.replace(/\D/g, "").slice(0, 10))}
                onKeyDown={(e) => e.key === "Enter" && submitMobile()}
                className="min-w-0 flex-1 bg-transparent text-sm text-gray-950 placeholder:text-gray-400 outline-none"
              />
            </div>
          </div>

          {error && <p className="mt-3 text-sm text-[#ff8a66]">{error}</p>}

          <button
            type="button"
            disabled={busy}
            onClick={submitMobile}
            className="mt-5 inline-flex h-[34px] w-full items-center justify-center gap-2 rounded-xl bg-[#FF4308] px-3 text-sm font-bold text-white transition-colors hover:bg-[#e83d07] disabled:opacity-40"
          >
            {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
            LOGIN
          </button>

          <p className="mt-2 text-xs font-medium leading-tight text-gray-950">
            By clicking on Login, I accept the{" "}
            <Link to="/terms" className="font-semibold underline hover:text-[#FF4308]">
              Terms &amp; Conditions
            </Link>{" "}
            &amp;{" "}
            <Link
              to="/terms"
              search={{ doc: "privacy" }}
              className="font-semibold underline hover:text-[#FF4308]"
            >
              Privacy Policy
            </Link>
          </p>
        </>
      ) : step === 2 ? (
        <>
          <h2 className="text-2xl font-bold text-gray-900">Sign up</h2>
          <p className="mt-2 text-sm text-gray-500">
            or{" "}
            <button
              type="button"
              onClick={() => {
                setStep(0);
                setError("");
              }}
              className="font-semibold text-[#FF4308] hover:underline"
            >
              login to your account
            </button>
          </p>

          <div className="mt-6 divide-y divide-gray-200 rounded-xl border border-gray-200">
            <div className="px-4 py-3">
              <label className="block text-xs font-medium text-gray-500" htmlFor="su-phone">
                Phone number
              </label>
              <div className="mt-1 flex items-center gap-2">
                <span className="text-sm text-gray-500">+91</span>
                <input
                  id="su-phone"
                  inputMode="numeric"
                  autoComplete="tel"
                  value={mobile}
                  onChange={(e) => setMobile(e.target.value.replace(/\D/g, "").slice(0, 10))}
                  placeholder="98765 43210"
                  className="flex-1 bg-transparent text-gray-900 placeholder:text-gray-400 outline-none"
                />
              </div>
            </div>
            <div className="px-4 py-3">
              <label className="block text-xs font-medium text-gray-500" htmlFor="su-name">
                Name
              </label>
              <input
                id="su-name"
                autoComplete="name"
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder="Your full name"
                className="mt-1 w-full bg-transparent text-gray-900 placeholder:text-gray-400 outline-none"
              />
            </div>
            <div className="px-4 py-3">
              <label className="block text-xs font-medium text-gray-500" htmlFor="su-email">
                Email
              </label>
              <input
                id="su-email"
                type="email"
                autoComplete="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && submitSignup()}
                placeholder="you@example.com"
                className="mt-1 w-full bg-transparent text-gray-900 placeholder:text-gray-400 outline-none"
              />
            </div>
          </div>

          {error && <p className="mt-3 text-sm text-[#ff8a66]">{error}</p>}

          <button
            type="button"
            disabled={busy}
            onClick={submitSignup}
            className="mt-5 inline-flex h-[34px] w-full items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-[#FF4308] to-[#ff7a44] px-3 text-white font-semibold shadow-[0_16px_40px_-16px_rgba(255,67,8,0.5)] transition-all hover:-translate-y-0.5 disabled:opacity-40 disabled:translate-y-0"
          >
            {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
            Continue
            <ArrowRight className="h-4 w-4" />
          </button>

          <p className="mt-4 text-xs text-gray-400">
            By creating an account you accept our{" "}
            <Link to="/terms" className="underline hover:text-gray-900">
              Terms &amp; Conditions
            </Link>{" "}
            and{" "}
            <Link to="/terms" search={{ doc: "privacy" }} className="underline hover:text-gray-900">
              Privacy Policy
            </Link>
            .
          </p>
        </>
      ) : (
        <>
          <button
            type="button"
            onClick={() => {
              setStep(0);
              setError("");
            }}
            className="inline-flex items-center gap-1.5 text-sm text-gray-500 hover:text-gray-900"
          >
            <ArrowLeft className="h-4 w-4" /> Change number
          </button>
          <h2 className="mt-4 text-2xl font-bold text-gray-900">Verify your number</h2>
          <p className="mt-2 text-sm text-gray-500">Code sent to +91 {digits}</p>

          <div className="mt-6 flex gap-3">
            {otp.map((d, i) => (
              <input
                key={i}
                ref={(el) => {
                  inputs.current[i] = el;
                }}
                inputMode="numeric"
                value={d}
                onChange={(e) => setDigit(i, e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Backspace" && !otp[i] && i > 0) inputs.current[i - 1]?.focus();
                  if (e.key === "Enter") verify();
                }}
                className="w-14 h-14 rounded-xl bg-gray-50 border border-gray-200 text-center text-2xl font-bold text-gray-900 outline-none focus:border-[#FF4308]"
              />
            ))}
          </div>

          {preview && (
            <p className="mt-4 rounded-lg bg-gray-50 px-3 py-2 text-xs text-gray-600">
              SMS delivery isn&apos;t connected yet — your code is{" "}
              <span className="font-bold text-gray-900">{preview}</span>
            </p>
          )}
          {error && <p className="mt-3 text-sm text-[#ff8a66]">{error}</p>}

          <button
            type="button"
            disabled={code.length !== 4 || busy}
            onClick={verify}
            className="mt-5 w-full inline-flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-[#FF4308] to-[#ff7a44] px-5 py-3 text-white font-semibold shadow-[0_16px_40px_-16px_rgba(255,67,8,0.5)] transition-all hover:-translate-y-0.5 disabled:opacity-40 disabled:translate-y-0"
          >
            {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : null}
            Verify &amp; continue
            <ArrowRight className="h-4 w-4" />
          </button>

          <button
            type="button"
            disabled={seconds > 0 || busy}
            onClick={() => sendCode()}
            className="mt-4 w-full text-sm text-gray-500 hover:text-gray-900 disabled:opacity-40"
          >
            {seconds > 0 ? `Resend code in ${seconds}s` : "Resend code"}
          </button>
        </>
      )}
    </div>
  );
}
