import { useEffect, useId, useState, type FormEvent } from "react";

import "./admin-auth.css";

interface ErrorEnvelopeBody {
  error?: {
    details?: { field_errors?: Array<{ message_key?: string }> };
  };
}

function adminErrorMessage(body: ErrorEnvelopeBody) {
  const key = body.error?.details?.field_errors?.[0]?.message_key;
  if (key === "auth.challenge.invalid") return "验证码不正确，请检查后重试。";
  if (key === "auth.challenge.expired") return "验证码已过期，请重新获取。";
  if (key === "auth.challenge.resend_too_soon") return "请等待倒计时结束后重新获取验证码。";
  if (key === "auth.account.suspended" || key === "admin.auth.not_allowed") return "无法使用管理员入口，请联系部署维护人员。";
  return "管理员登录暂时无法完成，请稍后重试。";
}

export function AdminAuthPage() {
  const emailId = useId();
  const codeId = useId();
  const [email, setEmail] = useState("");
  const [code, setCode] = useState("");
  const [registrationId, setRegistrationId] = useState<string>();
  const [countdown, setCountdown] = useState(0);
  const [sending, setSending] = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string>();
  const emailValid = /^[^@\s]+@[^@\s]+$/.test(email);

  useEffect(() => {
    if (countdown <= 0) return;
    const timer = window.setInterval(() => setCountdown((value) => Math.max(0, value - 1)), 1_000);
    return () => window.clearInterval(timer);
  }, [countdown]);

  async function sendCode() {
    if (!emailValid || sending || countdown > 0) return;
    setSending(true);
    setError(undefined);
    try {
      const response = await fetch("/api/v1/admin-auth/login/send", {
        body: JSON.stringify({ email }),
        credentials: "same-origin",
        headers: { "Content-Type": "application/json" },
        method: "POST",
      });
      const body = await response.json() as ErrorEnvelopeBody & { registration_id?: string };
      if (!response.ok || !body.registration_id) {
        setError(adminErrorMessage(body));
        return;
      }
      setRegistrationId(body.registration_id);
      setCountdown(60);
      window.requestAnimationFrame(() => document.getElementById(codeId)?.focus());
    } catch {
      setError("管理员登录暂时无法完成，请稍后重试。");
    } finally {
      setSending(false);
    }
  }

  async function completeLogin(event: FormEvent) {
    event.preventDefault();
    if (!registrationId || !/^[0-9]{6}$/.test(code) || submitting) return;
    setSubmitting(true);
    setError(undefined);
    try {
      const response = await fetch("/api/v1/admin-auth/login/complete", {
        body: JSON.stringify({ registration_id: registrationId, verification_code: code }),
        credentials: "same-origin",
        headers: {
          "Content-Type": "application/json",
          "Idempotency-Key": crypto.randomUUID().replaceAll("-", "") + crypto.randomUUID().replaceAll("-", ""),
        },
        method: "POST",
      });
      const body = await response.json() as ErrorEnvelopeBody;
      if (!response.ok) {
        setError(adminErrorMessage(body));
        return;
      }
      window.location.assign("/admin");
    } catch {
      setError("管理员登录暂时无法完成，请稍后重试。");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <main className="admin-auth-page">
      <div className="admin-auth-accent" aria-hidden="true" />
      <header className="admin-auth-header">
        <a className="admin-auth-wordmark" href="/" aria-label="Dada 普通用户登录">DADA</a>
      </header>
      <section className="admin-auth-panel">
        <p className="admin-auth-kicker">ADMIN</p>
        <h1 id="admin-auth-heading">管理员邮箱验证码登录</h1>
        <form onSubmit={completeLogin} noValidate>
          <label htmlFor={emailId}>管理员邮箱</label>
          <div className="admin-auth-send-row">
            <input
              id={emailId}
              autoComplete="email"
              inputMode="email"
              onChange={(event) => {
                setEmail(event.target.value);
                setRegistrationId(undefined);
                setCode("");
                setCountdown(0);
                setError(undefined);
              }}
              type="email"
              value={email}
            />
            <button
              aria-label="获取验证码"
              className="admin-auth-send"
              disabled={!emailValid || sending || countdown > 0}
              onClick={sendCode}
              type="button"
            >
              {sending ? "发送中" : countdown > 0 ? `${countdown}s` : "获取验证码"}
            </button>
          </div>
          {registrationId ? (
            <div className="admin-auth-code-field">
              <label htmlFor={codeId}>验证码</label>
              <input
                id={codeId}
                autoComplete="one-time-code"
                inputMode="numeric"
                maxLength={6}
                onChange={(event) => setCode(event.target.value.replace(/\D/g, "").slice(0, 6))}
                value={code}
              />
            </div>
          ) : null}
          {error ? <p className="admin-auth-error" role="alert">{error}</p> : null}
          <button className="admin-auth-submit" disabled={!registrationId || code.length !== 6 || submitting} type="submit">
            {submitting ? "登录中" : "登录后台"}
          </button>
        </form>
        <a className="admin-auth-return" href="/">返回普通用户登录</a>
      </section>
    </main>
  );
}
