"use client";

import { KeyRound, Lock, User } from "lucide-react";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { toast } from "sonner";
import { isAxiosError } from "axios";

import { AdminAuthCheckingScreen } from "@/components/admin/admin-auth-checking";
import { AdminLanguageSwitcher } from "@/components/admin/admin-language-switcher";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { getAdminCaptcha, postAdminLogin } from "@/api";
import { cn } from "@/lib/utils";
import { verifyStoredAdminSession } from "@/lib/admin-session-verify";
import {
  validateAdminLoginAccount,
  validateAdminPassword,
} from "@/lib/admin-input-validation";
import { authModuleMeta } from "@/modules/auth/meta";
import { useAdminSessionStore } from "@/stores/admin-session";
import { LotteryApiBizError } from "@/types/api/errors";

export function LoginForm() {
  const { t } = useTranslation(["auth", "common"]);
  const tRef = useTranslationRef(["auth", "common"]);
  const router = useRouter();
  const setBearerToken = useAdminSessionStore((s) => s.setBearerToken);
  const setAdminProfile = useAdminSessionStore((s) => s.setAdminProfile);

  const [account, setAccount] = useState("");
  const [password, setPassword] = useState("");
  const [captchaCode, setCaptchaCode] = useState("");
  const [captchaKey, setCaptchaKey] = useState<string | null>(null);
  const [captchaSrc, setCaptchaSrc] = useState<string | null>(null);

  const [loadingCaptcha, setLoadingCaptcha] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [checkingSession, setCheckingSession] = useState(true);

  const loadCaptcha = useCallback(async () => {
    setLoadingCaptcha(true);
    try {
      const data = await getAdminCaptcha();
      if (!data) {
        toast.error(tRef.current("captchaLoadFailed"));
        setCaptchaKey(null);
        setCaptchaSrc(null);

        return;
      }
      setCaptchaKey(data.captcha_key);
      setCaptchaSrc(`data:image/svg+xml;base64,${data.image_base64}`);
      setCaptchaCode("");
    } finally {
      setLoadingCaptcha(false);
    }
  }, [tRef]);

  useEffect(() => {
    let cancelled = false;

    async function bootstrap() {
      const ok = await verifyStoredAdminSession();
      if (cancelled) {
        return;
      }

      if (ok) {
        router.replace("/admin");
        router.refresh();
        return;
      }

      setCheckingSession(false);
      void loadCaptcha();
    }

    void bootstrap();

    return () => {
      cancelled = true;
    };
  }, [loadCaptcha, router]);

  async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!captchaKey || !captchaSrc) {
      toast.error(t("captchaRequired"));
      void loadCaptcha();

      return;
    }

    const accountIssue = validateAdminLoginAccount(account);
    if (accountIssue === "invalid_charset") {
      toast.error(
        t("accountInvalidCharset", {
          defaultValue: "登录账号只能使用字母、数字、点（.）、下划线和连字符",
        }),
      );
      return;
    }

    const passwordIssue = validateAdminPassword(password);
    if (passwordIssue === "too_short") {
      toast.error(
        t("passwordMinLength", { defaultValue: "密码至少需要 6 个字符" }),
      );
      return;
    }

    setSubmitting(true);
    try {
      const result = await postAdminLogin({
        account: account.trim(),
        password,
        captcha_key: captchaKey,
        captcha_code: captchaCode.trim(),
      });
      setBearerToken(result.token ?? "__cookie__");
      setAdminProfile(result.admin);
      toast.success(
        t("welcome", { name: result.admin.nickname || result.admin.username }),
      );
      router.replace("/admin");
      router.refresh();
    } catch (err) {
      void loadCaptcha();
      if (err instanceof LotteryApiBizError) {
        toast.error(err.message);

        return;
      }
      if (isAxiosError(err)) {
        toast.error(err.message || t("networkFailed"));

        return;
      }
      toast.error(t("loginFailed"));
    } finally {
      setSubmitting(false);
    }
  }

  if (checkingSession) {
    return <AdminAuthCheckingScreen variant="login" />;
  }

  const inputClass =
    "h-9 rounded-xl border-gray-200 bg-white pl-10 shadow-none transition-shadow focus-visible:ring-2 focus-visible:ring-red-600/20 xl:h-10";
  const fieldIconClass =
    "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-gray-400";

  return (
    <div
      className="relative flex h-dvh max-h-dvh w-full min-h-0 items-center justify-center overflow-y-auto px-4 py-4 xl:px-8 xl:py-10"
      data-admin-login-root
    >
      <div className="pointer-events-none absolute inset-0" aria-hidden>
        <Image
          src="/entry/login-pc-bg.png"
          alt=""
          fill
          sizes="100vw"
          className="object-cover object-center"
          priority
        />
      </div>

      <div
        className="relative z-10 flex min-h-[min(560px,calc(100dvh-2rem))] w-full max-w-[960px] overflow-hidden rounded-[1.5rem] bg-white shadow-[0_24px_80px_rgba(15,23,42,0.12)] xl:min-h-[min(640px,88vh)] xl:max-w-[1080px] xl:rounded-[2rem]"
        data-admin-login-card
      >
        <div
          className="relative hidden w-[min(48%,400px)] shrink-0 self-stretch overflow-hidden bg-[#f8fafc] md:block xl:w-[min(50%,460px)]"
          data-admin-login-hero-slot
        >
          <Image
            src="/entry/login-pc-hero.png"
            alt=""
            fill
            sizes="(max-width: 1280px) 400px, 460px"
            className="object-cover object-center"
            priority
          />
        </div>

        <div className="flex min-w-0 flex-1 flex-col px-6 py-5 xl:px-10 xl:py-10">
          <div className="flex justify-end">
            <div className="rounded-full border border-[#e4eaf4] bg-[#f8fafc] shadow-sm [&_[data-slot=dropdown-menu-trigger]]:h-9 [&_[data-slot=dropdown-menu-trigger]]:rounded-full">
              <AdminLanguageSwitcher />
            </div>
          </div>

          <div className="mx-auto flex w-full max-w-[23rem] flex-1 flex-col justify-center xl:max-w-[24rem]">
            <h1 className="text-[1.5rem] font-bold tracking-tight text-gray-900 xl:text-[1.75rem]">
              {t("loginTitle", { defaultValue: authModuleMeta.title })}
            </h1>
            <p className="mt-1.5 text-sm leading-relaxed text-gray-500 xl:mt-2">
              {t("loginSubtitle")}
            </p>

            <form className="mt-5 space-y-4 xl:mt-8 xl:space-y-5" onSubmit={onSubmit}>
              <div className="space-y-1.5">
                <Label htmlFor="admin-account">{t("account")}</Label>
                <div className="relative">
                  <User className={fieldIconClass} aria-hidden />
                  <Input
                    id="admin-account"
                    name="account"
                    autoComplete="username"
                    value={account}
                    onChange={(ev) => setAccount(ev.target.value)}
                    placeholder={t("accountPlaceholder")}
                    required
                    disabled={submitting}
                    className={inputClass}
                  />
                </div>
              </div>

              <div className="space-y-1.5">
                <Label htmlFor="admin-password">{t("password")}</Label>
                <div className="relative">
                  <Lock className={fieldIconClass} aria-hidden />
                  <Input
                    id="admin-password"
                    name="password"
                    type="password"
                    autoComplete="current-password"
                    value={password}
                    onChange={(ev) => setPassword(ev.target.value)}
                    placeholder={t("passwordPlaceholder")}
                    required
                    disabled={submitting}
                    className={inputClass}
                  />
                </div>
              </div>

              <div className="space-y-1.5">
                <Label htmlFor="admin-captcha">{t("captcha")}</Label>
                <div className="flex items-stretch gap-3">
                  <div className="relative min-w-0 flex-1">
                    <KeyRound className={fieldIconClass} aria-hidden />
                    <Input
                      id="admin-captcha"
                      name="captcha"
                      autoComplete="off"
                      value={captchaCode}
                      onChange={(ev) => setCaptchaCode(ev.target.value)}
                      placeholder={t("captchaPlaceholder")}
                      maxLength={32}
                      required
                      disabled={submitting}
                      className={inputClass}
                    />
                  </div>
                  <button
                    type="button"
                    className="flex h-9 min-w-[7.75rem] shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-xl border border-gray-200 bg-[#f4fbf6] px-2 transition-colors hover:bg-muted/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-red-600/20 disabled:pointer-events-none disabled:opacity-50 xl:h-10 xl:min-w-[8.5rem]"
                    onClick={() => void loadCaptcha()}
                    disabled={loadingCaptcha || submitting}
                    aria-label={loadingCaptcha ? t("captchaLoading") : t("captchaRefresh")}
                  >
                    {captchaSrc ? (
                      <Image
                        src={captchaSrc}
                        alt=""
                        width={160}
                        height={48}
                        unoptimized
                        className="pointer-events-none block h-full w-auto max-w-full object-contain"
                      />
                    ) : (
                      <span className="px-1 text-xs text-muted-foreground">
                        {loadingCaptcha ? t("captchaLoading") : t("captchaFetch")}
                      </span>
                    )}
                  </button>
                </div>
              </div>

              <Button
                type="submit"
                size="lg"
                className={cn(
                  "mt-2 h-11 w-full rounded-xl bg-red-600 text-base font-medium text-white shadow-sm hover:bg-red-700",
                  submitting && "translate-y-0",
                )}
                disabled={submitting}
              >
                {submitting ? t("submitting") : t("submit")}
              </Button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}
