// src/components/login-form.tsx
"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useTranslations } from "next-intl";
import { useState } from "react";
import { BrandLogo } from "@/components/brand-logo";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Field,
  FieldDescription,
  FieldGroup,
  FieldLabel,
  FieldSeparator,
} from "@/components/ui/field";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { absoluteUrl, cn } from "@/lib/utils";

const AFTER_LOGIN = "/keywords/reservoir";

export function LoginForm({
  googleEnabled,
  githubEnabled,
  redirectTo,
  defaultEmail,
  className,
  ...props
}: React.ComponentProps<"div"> & {
  googleEnabled?: boolean;
  githubEnabled?: boolean;
  redirectTo?: string;
  defaultEmail?: string;
}) {
  const t = useTranslations("Auth");
  const tCommon = useTranslations("Common");
  const router = useRouter();
  const [email, setEmail] = useState(defaultEmail ?? "");
  const [password, setPassword] = useState("");
  const [pending, setPending] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [magicSent, setMagicSent] = useState(false);
  // Where to land after auth (e.g. back to an invitation), default the app home.
  const callbackURL = absoluteUrl(redirectTo ?? AFTER_LOGIN);

  // The identifier field accepts an email OR a username. With no "@" we treat it
  // as a username (magic-link still needs a real email — see `sendMagic`).
  const isEmailIdentifier = email.includes("@");

  async function signInPassword(e: React.FormEvent) {
    e.preventDefault();
    setPending(true);
    setError(null);
    // Auto-detect: an "@" routes to /sign-in/email, otherwise /sign-in/username.
    // Username sign-in respects requireEmailVerification exactly like email.
    const res = isEmailIdentifier
      ? await authClient.signIn.email({ email, password, callbackURL })
      : await authClient.signIn.username({
          username: email,
          password,
          rememberMe: true,
        });
    if (res.error) {
      setPending(false);
      // The admin plugin rejects a banned user's sign-in with code BANNED_USER
      // (HTTP 403). Surface a localized sentence rather than the raw English
      // default message / bare code.
      setError(
        res.error.code === "BANNED_USER"
          ? t("bannedUser")
          : (res.error.message ?? t("loginFailed")),
      );
      return;
    }
    // 2FA-enabled accounts get `{ twoFactorRedirect: true }` instead of a
    // session — the password was correct but a second factor is still required.
    // Send them to the challenge page (the twoFactorClient also redirects, this
    // keeps the form from looking like it succeeded). Keep `pending` true so the
    // form stays disabled during navigation.
    if (
      (res.data as { twoFactorRedirect?: boolean } | null)?.twoFactorRedirect
    ) {
      router.push("/two-factor");
      return;
    }
    setPending(false);
  }

  async function sendMagic() {
    setPending(true);
    setError(null);
    const res = await authClient.signIn.magicLink({
      email,
      callbackURL,
    });
    setPending(false);
    if (res.error) setError(res.error.message ?? t("magicLinkFailed"));
    else setMagicSent(true);
  }

  return (
    <div className={cn("flex flex-col gap-6", className)} {...props}>
      <Card>
        <CardContent className="p-6 md:p-8">
          <form onSubmit={signInPassword}>
            <FieldGroup>
              <div className="flex flex-col items-center gap-2 text-center">
                <BrandLogo size={48} />
                <h1 className="font-bold text-2xl">{t("loginTitle")}</h1>
                <p className="text-balance text-muted-foreground">
                  {t("loginSubtitle")}
                </p>
              </div>
              <Field>
                <FieldLabel htmlFor="email">
                  {t("emailOrUsernameLabel")}
                </FieldLabel>
                {/* type=text (not email): a bare username has no "@" and would
                    fail native email validation. */}
                <Input
                  id="email"
                  type="text"
                  autoComplete="username"
                  placeholder={t("emailPlaceholder")}
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  required
                />
              </Field>
              <Field>
                <FieldLabel htmlFor="password">{t("passwordLabel")}</FieldLabel>
                <Input
                  id="password"
                  type="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                />
                <FieldDescription className="text-right">
                  <Link href="/forgot-password">{t("forgotPassword")}</Link>
                </FieldDescription>
              </Field>
              {error ? (
                <p className="text-destructive text-sm" role="alert">
                  {error}
                </p>
              ) : null}
              {magicSent ? (
                <p className="text-muted-foreground text-sm">
                  {t("magicLinkSent")}
                </p>
              ) : null}
              <Field>
                <Button type="submit" disabled={pending || !email}>
                  {pending ? "…" : t("signInButton")}
                </Button>
              </Field>
              <Field>
                {/* Magic links are emailed, so only offer it for an email
                    identifier — a username has no mailbox to send to. */}
                <Button
                  type="button"
                  variant="outline"
                  onClick={sendMagic}
                  disabled={pending || !isEmailIdentifier}
                >
                  {t("sendMagicLinkButton")}
                </Button>
              </Field>
              {googleEnabled || githubEnabled ? (
                <FieldSeparator>{tCommon("or")}</FieldSeparator>
              ) : null}
              {googleEnabled ? (
                <Field>
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() =>
                      authClient.signIn.social({
                        provider: "google",
                        callbackURL,
                      })
                    }
                  >
                    {t("continueWithGoogle")}
                  </Button>
                </Field>
              ) : null}
              {githubEnabled ? (
                <Field>
                  <Button
                    type="button"
                    variant="outline"
                    onClick={() =>
                      authClient.signIn.social({
                        provider: "github",
                        callbackURL,
                      })
                    }
                  >
                    {t("continueWithGitHub")}
                  </Button>
                </Field>
              ) : null}
              <FieldDescription className="text-center">
                {t("noAccount")}{" "}
                <Link href="/signup">{t("createAccountLink")}</Link>
              </FieldDescription>
            </FieldGroup>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}
