"use client";

import { useEffect, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { startAuthentication } from "@simplewebauthn/browser";
import {
  loginWithPassword,
  beginAuthentication,
  finishAuthentication,
} from "@/app/auth-actions";

type Props = {
  passkeysAvailable: boolean;
  next: string;
};

export default function AuthForm({ passkeysAvailable, next }: Props) {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();
  const [platformReady, setPlatformReady] = useState(false);
  const [pointerDevice, setPointerDevice] = useState(false);
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [passkeyError, setPasskeyError] = useState<string | null>(null);
  const [formError, setFormError] = useState<string | null>(null);

  useEffect(() => {
    if (typeof window === "undefined") return;
    setPointerDevice(
      window.matchMedia("(hover: hover) and (pointer: fine)").matches,
    );
    if (
      !passkeysAvailable ||
      typeof window.PublicKeyCredential === "undefined" ||
      typeof window.PublicKeyCredential
        .isUserVerifyingPlatformAuthenticatorAvailable !== "function"
    ) {
      return;
    }
    let cancelled = false;
    window.PublicKeyCredential
      .isUserVerifyingPlatformAuthenticatorAvailable()
      .then((ok) => {
        if (!cancelled) setPlatformReady(Boolean(ok));
      })
      .catch(() => {});
    return () => {
      cancelled = true;
    };
  }, [passkeysAvailable]);

  const showPasskey = passkeysAvailable && platformReady;
  const destination = next && next.startsWith("/") ? next : "/";

  function handlePasskey() {
    setPasskeyError(null);
    setFormError(null);
    startTransition(async () => {
      try {
        const options = await beginAuthentication();
        const response = await startAuthentication({ optionsJSON: options });
        const result = await finishAuthentication(response);
        if (result.ok) {
          router.push(destination);
          router.refresh();
        } else {
          setPasskeyError(result.error);
        }
      } catch (err) {
        const message =
          err instanceof Error ? err.message : "Passkey sign-in failed";
        if (
          message.toLowerCase().includes("notallowed") ||
          message.toLowerCase().includes("cancel")
        ) {
          setPasskeyError("Sign-in was cancelled");
        } else {
          setPasskeyError(message);
        }
      }
    });
  }

  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setFormError(null);
    setPasskeyError(null);
    startTransition(async () => {
      const result = await loginWithPassword(username, password);
      if (result.ok) {
        router.push(destination);
        router.refresh();
      } else {
        setFormError(result.error);
      }
    });
  }

  return (
    <div className="flex min-h-[calc(100vh-12rem)] items-center justify-center px-2">
      <div className="w-full max-w-md">
        <div className="rounded-2xl bg-white p-8 ring-1 ring-zinc-200/60 sm:p-10">
          <div className="flex items-center gap-3">
            <span className="flex h-8 w-8 items-center justify-center rounded-lg bg-zinc-900 text-[11px] font-semibold tracking-tight text-white">
              CM
            </span>
            <h1 className="text-lg font-semibold tracking-tight text-zinc-900">
              Sign in
            </h1>
          </div>
          <p className="mt-1 text-[13px] text-zinc-500">
            CM Bot V2 — operator console
          </p>

          {showPasskey && (
            <>
              <div className="mt-6 flex flex-col gap-2">
                <button
                  type="button"
                  onClick={handlePasskey}
                  disabled={isPending}
                  className="inline-flex items-center justify-center gap-2 rounded-full bg-zinc-900 px-4 py-2.5 text-xs font-medium text-white transition-colors hover:bg-zinc-700 disabled:opacity-60"
                >
                  <svg
                    aria-hidden="true"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    className="h-3.5 w-3.5"
                  >
                    <path d="M7 11V8a5 5 0 0 1 10 0v3" />
                    <rect x="5" y="11" width="14" height="10" rx="2" />
                  </svg>
                  {isPending ? "…" : "Sign in with passkey"}
                </button>
                {passkeyError && (
                  <p className="font-mono text-[11px] text-red-600" role="alert">
                    {passkeyError}
                  </p>
                )}
              </div>

              <div className="my-6 flex items-center gap-3">
                <span className="h-px flex-1 bg-zinc-200" />
                <span className="text-[10px] font-medium uppercase tracking-wider text-zinc-400">
                  or
                </span>
                <span className="h-px flex-1 bg-zinc-200" />
              </div>
            </>
          )}

          <form
            onSubmit={handleSubmit}
            className={`flex flex-col gap-3 ${showPasskey ? "" : "mt-6"}`}
          >
            <label className="flex flex-col gap-1">
              <span className="text-[11px] font-medium uppercase tracking-wider text-zinc-500">
                Agent ID
              </span>
              <input
                name="username"
                type="text"
                autoComplete="username"
                autoCapitalize="off"
                autoCorrect="off"
                spellCheck={false}
                autoFocus={pointerDevice}
                value={username}
                onChange={(e) => setUsername(e.target.value)}
                disabled={isPending}
                className="w-full min-w-0 rounded-md border-0 bg-zinc-100 px-3 py-2 font-mono text-base text-zinc-900 outline-none ring-1 ring-zinc-300 transition-colors focus:bg-white focus:ring-2 focus:ring-zinc-900 disabled:opacity-60 sm:text-[13px]"
              />
            </label>

            <label className="flex flex-col gap-1">
              <span className="text-[11px] font-medium uppercase tracking-wider text-zinc-500">
                Password
              </span>
              <input
                name="password"
                type="password"
                autoComplete="current-password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                disabled={isPending}
                className="w-full min-w-0 rounded-md border-0 bg-zinc-100 px-3 py-2 font-mono text-base text-zinc-900 outline-none ring-1 ring-zinc-300 transition-colors focus:bg-white focus:ring-2 focus:ring-zinc-900 disabled:opacity-60 sm:text-[13px]"
              />
            </label>

            <button
              type="submit"
              disabled={isPending || !username || !password}
              className={`mt-2 inline-flex items-center justify-center rounded-full px-4 py-2.5 text-xs font-medium transition-colors disabled:opacity-60 ${
                showPasskey
                  ? "bg-zinc-100 text-zinc-900 hover:bg-zinc-200"
                  : "bg-zinc-900 text-white hover:bg-zinc-700"
              }`}
            >
              {isPending ? "…" : "Sign in"}
            </button>

            {formError && (
              <p className="font-mono text-[11px] text-red-600" role="alert">
                {formError}
              </p>
            )}
          </form>

          <div className="mt-6 flex items-center gap-2 rounded-xl bg-emerald-50 px-3 py-2 ring-1 ring-emerald-100">
            <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-emerald-500" />
            <p className="text-[11px] text-emerald-900/80">
              Forgot the password? Please contact IT.
            </p>
          </div>
        </div>
      </div>
    </div>
  );
}
