import { toast } from "sonner";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";
import logoSrc from "../assets/logo.png";
import logoTitleSrc from "../assets/logo-title.png";
import {
  ACCESS_TOKEN_KEY,
  persistTokens,
  persistUser,
  sendAuthSmsCode,
  smsLogin,
} from "../api/auth";
import { tw } from "../utils/tw";

/** 发送验证码成功后，按钮冷却秒数 */
const SMS_RESEND_COOLDOWN_SEC = 60;
const LOGO_SRC = logoSrc;
const LOGIN_TITLE_SRC = logoTitleSrc;

/** 短信验证码登录页：校验本地 token、发送验证码、提交登录 */
export default function LoginPage() {
  const navigate = useNavigate();
  const [phone, setPhone] = useState("");
  const [code, setCode] = useState("");
  const [sendingSms, setSendingSms] = useState(false);
  const [smsCooldown, setSmsCooldown] = useState(0);
  const [loggingIn, setLoggingIn] = useState(false);
  const [phoneError, setPhoneError] = useState("");
  const [codeError, setCodeError] = useState("");

  /** 已登录则直接进入首页，避免重复停留在登录页 */
  useEffect(() => {
    const accessToken = window.localStorage.getItem(ACCESS_TOKEN_KEY);
    if (accessToken) {
      navigate("/", { replace: true });
    }
  }, [navigate]);

  const smsCountdownActive = smsCooldown > 0;
  /** 验证码发送冷却：每秒递减，到 0 后允许再次发送 */
  useEffect(() => {
    if (!smsCountdownActive) return undefined;
    const id = window.setInterval(() => {
      setSmsCooldown((s) => (s <= 1 ? 0 : s - 1));
    }, 1000);
    return () => window.clearInterval(id);
  }, [smsCountdownActive]);

  /**
   * 提交手机号与验证码，调用登录接口；成功则持久化 token 并跳转首页。
   */
  const onLogin = async () => {
    const formattedPhone = formatPhoneForApi(phone);
    if (!formattedPhone) {
      setPhoneError("请输入正确的手机号");
      return;
    }
    const trimmedCode = code.trim();
    if (!trimmedCode) {
      setCodeError("请输入验证码");
      return;
    }
    if (loggingIn) return;
    setLoggingIn(true);
    try {
      const data = await smsLogin(formattedPhone, trimmedCode);
      persistTokens(data.accessToken, data.refreshToken);
      persistUser(data.user);
      toast.success("登录成功");
      navigate("/", { replace: true });
    } catch (error) {
      const text = error instanceof Error ? error.message : "登录失败";
      toast.error(text || "登录失败");
    } finally {
      setLoggingIn(false);
    }
  };

  /**
   * 将用户输入规范为后端要求的国际格式（如 `+8613xxxxxxxx`）。
   * @returns 无法识别时返回 `null`
   */
  function formatPhoneForApi(input: string): string | null {
    const cleaned = input.trim().replace(/\s+/g, "");
    if (!cleaned) return null;
    if (cleaned.startsWith("+")) return cleaned;
    if (/^86\d{11}$/.test(cleaned)) return `+${cleaned}`;
    if (/^1\d{10}$/.test(cleaned)) return `+86${cleaned}`;
    return null;
  }

  /**
   * 请求发送短信验证码；成功后启动冷却，若接口返回 `testCode` 则自动填入（联调环境）。
   */
  const onSendSmsCode = async () => {
    const formattedPhone = formatPhoneForApi(phone);
    if (!formattedPhone) {
      setPhoneError("请输入正确的手机号");
      return;
    }
    if (sendingSms || smsCooldown > 0) return;
    setSendingSms(true);
    try {
      const { testCode } = await sendAuthSmsCode(formattedPhone);
      if (testCode) {
        setCode(testCode);
      }
      setSmsCooldown(SMS_RESEND_COOLDOWN_SEC);
      toast.success("验证码已发送");
    } catch (error) {
      const text = error instanceof Error ? error.message : "验证码发送失败";
      toast.error(text || "验证码发送失败");
    } finally {
      setSendingSms(false);
    }
  };

  /** 手机号、验证码输入组共用外观；由 InputGroup 自身承担边框，避免双层边框 */
  const loginGroupClass = tw(
    "h-[48px] rounded-full border-gray-200 bg-gray-50 px-4",
    "transition-colors has-[[data-slot=input-group-control]:focus-visible]:border-gray-300",
    "has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot=input-group-control]:focus-visible]:ring-[#1677ff]/15",
  );

  const loginGroupStateClass = (error: string) =>
    tw(
      loginGroupClass,
      error
        ? "border-red-400 has-[[data-slot=input-group-control]:focus-visible]:border-red-400 has-[[data-slot=input-group-control]:focus-visible]:ring-red-500/15"
        : "",
    );

  return (
    <main
      className={tw(
        "flex h-dvh w-full items-center justify-center",
        "overflow-hidden bg-white px-4",
      )}
    >
      <section className="w-[325px] -translate-y-6">
        <div className="mb-7 flex items-center justify-center">
          <img
            src={LOGO_SRC}
            alt="ChatOne Logo"
            className="h-10 w-10 shrink-0 object-contain"
            decoding="async"
          />
          <img
            src={LOGIN_TITLE_SRC}
            alt="chatone"
            className="h-auto w-[150px] object-contain object-left"
            decoding="async"
          />
        </div>

        <div className="space-y-5">
          <div>
            <InputGroup className={loginGroupStateClass(phoneError)}>
              <InputGroupInput
                aria-invalid={!!phoneError}
                placeholder="请输入手机号"
                value={phone}
                onChange={(e) => {
                  setPhone(e.target.value);
                  if (phoneError) setPhoneError("");
                }}
                className="h-auto bg-transparent px-0 py-0 text-[14px] md:text-[14px] shadow-none focus-visible:ring-0"
              />
              <InputGroupAddon align="inline-start" className="mr-2 text-[14px] text-[#222]">
                +86
              </InputGroupAddon>
            </InputGroup>
            <p
              className={tw(
                "mt-1 min-h-4 px-4 text-xs text-red-500",
                phoneError ? "visible" : "invisible",
              )}
            >
              {phoneError || " "}
            </p>
          </div>

          <div>
            <InputGroup className={loginGroupStateClass(codeError)}>
              <InputGroupInput
                aria-invalid={!!codeError}
                placeholder="请输入验证码"
                value={code}
                onChange={(e) => {
                  setCode(e.target.value);
                  if (codeError) setCodeError("");
                }}
                className="h-auto bg-transparent px-0 py-0 text-[14px] md:text-[14px] shadow-none focus-visible:ring-0"
              />
              <InputGroupAddon align="inline-end" className="pr-0">
                <span className="mx-2 h-5 w-px bg-gray-200" />
                <Button
                  type="button"
                  variant="link"
                  size="sm"
                  disabled={smsCooldown > 0}
                  onClick={() => {
                    void onSendSmsCode();
                  }}
                  className={tw(
                    "h-auto min-w-0 shrink-0 p-0 text-[14px] md:text-[14px] font-medium",
                    "text-[#1677ff] hover:text-[#0f6eea] hover:no-underline",
                    "disabled:text-neutral-400 disabled:opacity-100",
                  )}
                >
                  {sendingSms
                    ? "发送中..."
                    : smsCooldown > 0
                      ? `${smsCooldown}s 后重发`
                      : "发送验证码"}
                </Button>
              </InputGroupAddon>
            </InputGroup>
            <p
              className={tw(
                "mt-1 min-h-4 px-4 text-xs text-red-500",
                codeError ? "visible" : "invisible",
              )}
            >
              {codeError || " "}
            </p>
          </div>

          <p className="block text-[12px] leading-6 text-[#81858c] py-2">
            注册登录即代表已阅读并同意我们的{" "}
            <a href="#" className="text-[#333] underline">
              用户协议
            </a>{" "}
            与{" "}
            <a href="#" className="text-[#333] underline">
              隐私政策
            </a>
            ，未注册的手机号将自动注册
          </p>

          <Button
            type="button"
            size="lg"
            disabled={loggingIn}
            onClick={() => {
              void onLogin();
            }}
            className="mt-1 h-[46px] w-full rounded-full text-[14px] md:text-[14px]"
          >
            {loggingIn ? "登录中..." : "登录"}
          </Button>
        </div>
      </section>
    </main>
  );
}
