"use client"

import * as React from "react"
import Link from "next/link"
import { useRouter, useSearchParams } from "next/navigation"
import { signIn } from "next-auth/react"
import { useTranslations } from "next-intl"
import { Button } from "@/shared/components/ui/button"
import { Input } from "@/shared/components/ui/input"
import { Label } from "@/shared/components/ui/label"
import { Alert, AlertDescription } from "@/shared/components/ui/alert"
import { cn } from "@/shared/lib/utils"
import { Loader2, Github, ShieldCheck, AlertCircle } from "lucide-react"
import { preflightTwoFactorAction } from "@/modules/auth/actions"

type LoginFormProps = React.HTMLAttributes<HTMLDivElement>

/** 触发账户锁定提示的失败次数阈值（与后端 PASSWORD_RULES.maxFailedAttempts 对齐） */
const LOCK_HINT_THRESHOLD = 3

/** 简单邮箱格式校验（与服务端 Zod 校验对齐，仅用于前置拦截） */
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/

export function LoginForm({ className, ...props }: LoginFormProps) {
  const t = useTranslations("auth.login")
  const [isLoading, setIsLoading] = React.useState<boolean>(false)
  const [requiresTwoFactor, setRequiresTwoFactor] = React.useState<boolean>(false)
  const [totpCode, setTotpCode] = React.useState<string>("")
  const [error, setError] = React.useState<string>("")
  const [failedAttempts, setFailedAttempts] = React.useState<number>(0)
  const router = useRouter()
  const searchParams = useSearchParams()

  /** 清除错误并重置为初始状态（用于输入变更时） */
  const clearError = React.useCallback(() => {
    setError("")
  }, [])

  function validateCredentials(email: string, password: string): string | null {
    if (!email.trim()) return t("errors.emailRequired")
    if (!EMAIL_RE.test(email)) return t("errors.emailFormat")
    if (!password) return t("errors.passwordRequired")
    return null
  }

  async function onSubmit(event: React.SyntheticEvent) {
    event.preventDefault()
    setError("")

    const form = event.currentTarget as HTMLFormElement
    const formData = new FormData(form)
    const email = String(formData.get("email") ?? "").trim()
    const password = String(formData.get("password") ?? "")
    const callbackUrl = searchParams.get("callbackUrl") ?? "/dashboard"

    // 客户端校验：2FA 模式下校验 totpCode，否则校验 email/password
    if (requiresTwoFactor) {
      if (!totpCode.trim()) {
        setError(t("errors.totpRequired"))
        return
      }
    } else {
      const validationError = validateCredentials(email, password)
      if (validationError) {
        setError(validationError)
        return
      }
    }

    setIsLoading(true)

    // 首次提交：检查是否需要 2FA
    if (!requiresTwoFactor) {
      try {
        const preflight = await preflightTwoFactorAction(email)
        if (preflight.required) {
          setRequiresTwoFactor(true)
          setIsLoading(false)
          return
        }
      } catch {
        // 预检失败时静默降级为普通登录
      }
    }

    const result = await signIn("credentials", {
      redirect: false,
      email,
      password,
      totpCode: requiresTwoFactor ? totpCode : undefined,
      callbackUrl,
    })

    setIsLoading(false)

    if (!result?.error) {
      router.push(result?.url ?? callbackUrl)
      router.refresh()
    } else {
      // 失败计数：仅在非 2FA 模式下累计（2FA 失败不计入账户锁定计数）
      const nextAttempts = requiresTwoFactor ? failedAttempts : failedAttempts + 1
      setFailedAttempts(nextAttempts)

      // 根据失败次数与上下文选择错误消息
      if (requiresTwoFactor) {
        setError(t("errors.invalid2fa"))
      } else if (nextAttempts >= LOCK_HINT_THRESHOLD) {
        // 达到阈值后切换为更严重的提示（账户可能已被锁定）
        setError(t("errors.tooManyAttempts"))
      } else {
        setError(t("errors.invalidCredentials"))
      }
    }
  }

  /** 切换回普通登录模式时重置 2FA 相关状态与失败计数 */
  function handleBackToLogin() {
    setRequiresTwoFactor(false)
    setTotpCode("")
    setError("")
  }

  const showLockHint = failedAttempts >= LOCK_HINT_THRESHOLD && !requiresTwoFactor

  return (
    <div className={cn("grid gap-6", className)} {...props}>
      <div className="flex flex-col space-y-2 text-center">
        <h1 className="text-2xl font-semibold tracking-tight">
          {t("title")}
        </h1>
        <p className="text-sm text-muted-foreground">
          {requiresTwoFactor ? t("subtitle2fa") : t("subtitle")}
        </p>
      </div>
      <form onSubmit={onSubmit}>
        <div className="grid gap-4">
          {!requiresTwoFactor ? (
            <>
              <div className="grid gap-2">
                <Label htmlFor="email">{t("email")}</Label>
                <Input
                  id="email"
                  name="email"
                  placeholder="name@example.com"
                  type="email"
                  autoCapitalize="none"
                  autoComplete="email"
                  autoCorrect="off"
                  disabled={isLoading}
                  onChange={clearError}
                />
              </div>
              <div className="grid gap-2">
                <div className="flex items-center justify-between">
                  <Label htmlFor="password">{t("password")}</Label>
                  <Link
                    href="/forgot-password"
                    className="text-sm font-medium text-muted-foreground hover:underline"
                  >
                    {t("forgotPassword")}
                  </Link>
                </div>
                <Input
                  id="password"
                  name="password"
                  type="password"
                  autoComplete="current-password"
                  disabled={isLoading}
                  onChange={clearError}
                />
              </div>
            </>
          ) : (
            <div className="grid gap-2">
              <Label htmlFor="totpCode" className="flex items-center gap-1.5">
                <ShieldCheck className="h-4 w-4" />
                {t("totpLabel")}
              </Label>
              <Input
                id="totpCode"
                name="totpCode"
                type="text"
                inputMode="numeric"
                autoComplete="one-time-code"
                placeholder="123456"
                maxLength={8}
                value={totpCode}
                onChange={(e) => {
                  setTotpCode(e.target.value)
                  clearError()
                }}
                disabled={isLoading}
                autoFocus
              />
              <p className="text-xs text-muted-foreground">
                {t("totpHint")}
              </p>
              <button
                type="button"
                onClick={handleBackToLogin}
                className="text-xs text-muted-foreground hover:underline justify-self-start"
                disabled={isLoading}
              >
                ← {t("backToLogin")}
              </button>
            </div>
          )}

          {error ? (
            <Alert className="border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive">
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>{error}</AlertDescription>
            </Alert>
          ) : null}

          {/* 账户锁定提示：达到失败阈值后展示，引导用户重置密码 */}
          {showLockHint && !error ? (
            <Alert>
              <AlertCircle className="h-4 w-4" />
              <AlertDescription>{t("errors.accountLockedHint")}</AlertDescription>
            </Alert>
          ) : null}

          <Button disabled={isLoading}>
            {isLoading && (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            )}
            {requiresTwoFactor ? t("verifyAndSignIn") : t("signIn")}
          </Button>
        </div>
      </form>
      <div className="relative">
        <div className="absolute inset-0 flex items-center">
          <span className="w-full border-t" />
        </div>
        <div className="relative flex justify-center text-xs uppercase">
          <span className="bg-background px-2 text-muted-foreground">
            {t("orContinueWith")}
          </span>
        </div>
      </div>
      <Button variant="outline" type="button" disabled={isLoading}>
        {isLoading ? (
          <Loader2 className="mr-2 h-4 w-4 animate-spin" />
        ) : (
          <Github className="mr-2 h-4 w-4" />
        )}{" "}
        GitHub
      </Button>
      <p className="px-8 text-center text-sm text-muted-foreground">
        {t("noAccount")}{" "}
        <Link
          href="/register"
          className="underline underline-offset-4 hover:text-primary"
        >
          {t("register")}
        </Link>
      </p>
    </div>
  )
}
