"use client";

import { useState, Suspense } from "react";
import { signIn } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import TurnstileWidget from "@/components/shared/turnstile-widget";

// Reject anything that isn't a same-origin path. Blocks `//evil.com` and
// `https://evil.com` from being passed in via ?callbackUrl=… (open redirect).
function safeCallback(raw: string | null): string {
  if (!raw) return "/";
  if (!raw.startsWith("/")) return "/";
  if (raw.startsWith("//")) return "/";
  return raw;
}

function LoginForm() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const callbackUrl = safeCallback(searchParams.get("callbackUrl"));
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [totpCode, setTotpCode] = useState("");
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const [captchaToken, setCaptchaToken] = useState("");

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setError("");
    setLoading(true);

    try {
      const result = await signIn("credentials", {
        email,
        password,
        totpCode: totpCode.trim(),
        redirect: false,
      });

      if (result?.error) {
        // R15 A.1: NextAuth v5 collapses all authorize() throws into
        // CredentialsSignin, so we can't distinguish "wrong password" from
        // "missing/invalid TOTP" on the wire. Hint the user that the 2FA
        // field is required when 2FA is enabled.
        setError(
          "Invalid email or password. If 2FA is enabled, the code is required."
        );
      } else {
        router.push(callbackUrl);
        router.refresh();
      }
    } catch {
      setError("An unexpected error occurred");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="bg-surface rounded-lg p-8 shadow-lg">
      <h1 className="text-2xl font-bold text-text mb-6 text-center">
        Sign In
      </h1>

      {error && (
        <div className="bg-red-500/10 border border-red-500/50 text-red-400 rounded-md p-3 mb-4 text-sm">
          {error}
        </div>
      )}

      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label htmlFor="email" className="block text-sm font-medium text-text-muted mb-1">
            Email
          </label>
          <input
            id="email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
            autoComplete="email"
            inputMode="email"
            className="w-full rounded-md border border-surface-light bg-background px-3 py-2 text-text placeholder-text-muted focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
            placeholder="your@email.com"
          />
        </div>

        <div>
          <label htmlFor="password" className="block text-sm font-medium text-text-muted mb-1">
            Password
          </label>
          <input
            id="password"
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
            autoComplete="current-password"
            className="w-full rounded-md border border-surface-light bg-background px-3 py-2 text-text placeholder-text-muted focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
            placeholder="••••••••"
          />
        </div>

        <div>
          <label htmlFor="totpCode" className="block text-sm font-medium text-text-muted mb-1">
            2FA Code <span className="text-text-muted/60">(if enabled)</span>
          </label>
          <input
            id="totpCode"
            type="text"
            inputMode="numeric"
            pattern="[0-9]{6}"
            maxLength={6}
            autoComplete="one-time-code"
            value={totpCode}
            onChange={(e) => setTotpCode(e.target.value.replace(/\D/g, "").slice(0, 6))}
            className="w-full rounded-md border border-surface-light bg-background px-3 py-2 text-text placeholder-text-muted font-mono tracking-widest focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary"
            placeholder="123456"
          />
        </div>

        <TurnstileWidget onVerify={setCaptchaToken} />

        <div className="flex items-center justify-between text-sm">
          <Link href="/forgot-password" className="text-primary hover:text-primary-dark">
            Forgot password?
          </Link>
        </div>

        <button
          type="submit"
          disabled={loading || !captchaToken}
          className="w-full rounded-md bg-primary py-2.5 text-white font-medium hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          aria-describedby={!captchaToken ? "captcha-help" : undefined}
        >
          {loading ? "Signing in..." : !captchaToken ? "Complete the security check first" : "Sign In"}
        </button>
        {!captchaToken && (
          <p id="captcha-help" className="text-xs text-text-muted text-center">
            Complete the security check above to enable sign in.
          </p>
        )}
      </form>

      <p className="mt-6 text-center text-sm text-text-muted">
        Don&apos;t have an account?{" "}
        <Link href="/register" className="text-primary hover:text-primary-dark font-medium">
          Register
        </Link>
      </p>
    </div>
  );
}

export default function LoginPage() {
  return (
    <Suspense fallback={<div className="text-center text-text-muted">Loading...</div>}>
      <LoginForm />
    </Suspense>
  );
}
