"use client";

import { useRouter } from "next/navigation";
import { useCallback, useRef, useState } from "react";

import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { getBrivenAuth } from "@/lib/auth";
import { establishPortalSession } from "@/lib/portal-session";

/** Most Briven email OTPs are 6 digits — verify as soon as that many land. */
const OTP_LEN = 6;

/**
 * Email OTP + Konnos OAuth (magic link off — use Briven Auth Providers).
 * After OTP success we mint a first-party portal session so the dashboard sticks.
 */
export function BrivenPasswordlessSignIn({
  redirectTo = "/portal/dashboard",
}: {
  redirectTo?: string;
}) {
  const router = useRouter();
  const auth = getBrivenAuth();

  const [email, setEmail] = useState("");
  const [otp, setOtp] = useState("");
  const [otpSent, setOtpSent] = useState(false);
  const [busy, setBusy] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const verifyingRef = useRef(false);
  const lastTriedRef = useRef("");

  const finishLogin = useCallback(
    async (userId: string, loginEmail: string) => {
      await establishPortalSession({ userId, email: loginEmail });
      window.dispatchEvent(new Event("krypco-auth-change"));
      router.push(redirectTo);
      router.refresh();
    },
    [redirectTo, router],
  );

  const verifyOtp = useCallback(
    async (code: string) => {
      if (!auth) return;
      const cleaned = code.replace(/\s/g, "").trim();
      if (cleaned.length < 4) return;
      if (verifyingRef.current) return;
      if (lastTriedRef.current === cleaned) return;

      verifyingRef.current = true;
      lastTriedRef.current = cleaned;
      setError(null);
      setBusy(true);
      setMessage("Checking code…");
      try {
        const loginEmail = email.trim().toLowerCase();
        const r = await auth.signIn.otpVerify({
          email: loginEmail,
          otp: cleaned,
        });
        if (!r.ok) {
          setError(r.message || r.code);
          setMessage(null);
          lastTriedRef.current = "";
          return;
        }
        const userId =
          ("userId" in r && typeof r.userId === "string" && r.userId) ||
          `user_${loginEmail}`;
        setMessage("Signed in — opening dashboard…");
        await finishLogin(userId, loginEmail);
      } catch (e) {
        setError(e instanceof Error ? e.message : "Could not verify code");
        setMessage(null);
        lastTriedRef.current = "";
      } finally {
        setBusy(false);
        verifyingRef.current = false;
      }
    },
    [auth, email, finishLogin],
  );

  if (!auth) {
    return (
      <p className="text-sm text-muted-foreground">
        Briven Auth key missing in environment.
      </p>
    );
  }

  async function sendOtp() {
    if (!auth) return;
    setError(null);
    setMessage(null);
    setBusy(true);
    try {
      const r = await auth.signIn.otpRequest({
        email: email.trim(),
        redirectTo,
      });
      if (!r.ok) {
        setError(r.message || r.code);
        return;
      }
      setOtpSent(true);
      setOtp("");
      lastTriedRef.current = "";
      setMessage("Check your email for a one-time code — paste it below.");
    } catch (e) {
      setError(e instanceof Error ? e.message : "Could not send code");
    } finally {
      setBusy(false);
    }
  }

  function onOtpChange(raw: string) {
    const digits = raw.replace(/\D/g, "").slice(0, OTP_LEN);
    setOtp(digits);
    setError(null);
    if (digits.length === OTP_LEN) {
      void verifyOtp(digits);
    }
  }

  function startKonnos() {
    if (!auth) return;
    setError(null);
    const { redirectUrl } = auth.signIn.social({
      provider: "konnos",
      redirectTo:
        typeof window !== "undefined"
          ? `${window.location.origin}${redirectTo}`
          : redirectTo,
    });
    window.location.assign(redirectUrl);
  }

  return (
    <div className="space-y-5">
      <div className="space-y-2">
        <label htmlFor="briven-email" className="text-sm font-medium">
          Email
        </label>
        <Input
          id="briven-email"
          type="email"
          autoComplete="email"
          placeholder="you@company.com"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          disabled={busy}
        />
      </div>

      <Button
        type="button"
        className="w-full"
        disabled={busy || !email.includes("@")}
        onClick={() => void sendOtp()}
      >
        {otpSent ? "Resend email code" : "Send email code"}
      </Button>

      {otpSent ? (
        <div className="flex flex-col items-center border-t border-border pt-6 text-center">
          <label
            htmlFor="briven-otp"
            className="mb-3 text-sm font-medium text-foreground"
          >
            Code from email
          </label>
          <Input
            id="briven-otp"
            inputMode="numeric"
            autoComplete="one-time-code"
            autoFocus
            placeholder="······"
            maxLength={OTP_LEN}
            value={otp}
            onChange={(e) => onOtpChange(e.target.value)}
            disabled={busy}
            aria-label="Six-digit code from your email"
            className="mx-auto h-14 w-full max-w-[16rem] text-center font-mono text-2xl tracking-[0.35em] tabular-nums"
          />
          <p className="mt-3 max-w-xs text-xs text-muted-foreground leading-relaxed">
            Paste or type all {OTP_LEN} digits — we check the code and open the
            dashboard automatically.
          </p>
          {busy && otp.length === OTP_LEN ? (
            <p className="mt-2 text-sm text-muted-foreground" role="status">
              Signing you in…
            </p>
          ) : null}
          {otp.length >= 4 && otp.length < OTP_LEN ? (
            <Button
              type="button"
              className="mt-4"
              disabled={busy}
              onClick={() => void verifyOtp(otp)}
            >
              Verify and continue
            </Button>
          ) : null}
        </div>
      ) : null}

      <div className="relative py-2">
        <div className="absolute inset-0 flex items-center">
          <span className="w-full border-t border-border" />
        </div>
        <div className="relative flex justify-center text-xs uppercase tracking-wide text-muted-foreground">
          <span className="bg-card px-2">or</span>
        </div>
      </div>

      <Button
        type="button"
        variant="outline"
        className="inline-flex w-full items-center justify-center gap-2"
        disabled={busy}
        onClick={startKonnos}
      >
        {/* eslint-disable-next-line @next/next/no-img-element */}
        <img
          src="/konnos.svg"
          alt=""
          width={20}
          height={20}
          className="h-5 w-5 shrink-0 object-contain"
          aria-hidden
        />
        Continue with Konnos
      </Button>

      {message ? (
        <p className="text-center text-sm text-proof" role="status">
          {message}
        </p>
      ) : null}
      {error ? (
        <p className="text-center text-sm text-pending" role="alert">
          {error}
        </p>
      ) : null}

      <p className="text-xs text-muted-foreground leading-relaxed">
        Sign in with a one-time email code. Magic links are off. MFA (if
        enrolled) is handled by Briven after the first factor.
      </p>
    </div>
  );
}
