import {
  CameraOutlined,
  CheckOutlined,
  CheckCircleFilled,
  CloseOutlined,
  DeleteOutlined,
  DownloadOutlined,
  EditOutlined,
  FileImageOutlined,
  FolderOpenOutlined,
  LockOutlined,
  MailOutlined,
  MobileOutlined,
  PhoneOutlined,
  PlayCircleOutlined,
  PlusOutlined,
  SafetyOutlined,
  ShareAltOutlined,
  UserOutlined,
} from "@ant-design/icons";
import { useEffect, useMemo, useRef, useState, type ChangeEvent, type DragEvent, type FormEvent, type KeyboardEvent } from "react";
import { createPortal } from "react-dom";
import "../../styles/pages/profile.css";
import { aiGenerationClient } from "../../api/aiGenerationClient";
import { assetClient } from "../../api/assetClient";
import { communityClient, type ServerCommunityCase } from "../../api/communityClient";
import { keyServerClient } from "../../api/keyServerClient";
import { isServerRequestError } from "../../api/serverConnection";
import { ossAssets } from "../../data/ossAssets";
import type { WebAuthMode, WebGenerationPreviewTask, WebProjectSummary, WebUsageSummary, WebUserSession } from "../../types";
import type { SavedAssetItem } from "../assets/localAssetStore";
import { downloadResultAsset } from "../workbench/workbenchDownload";

interface ProfilePageProps {
  session: WebUserSession | null;
  usage: WebUsageSummary;
  projects: WebProjectSummary[];
  tasks: WebGenerationPreviewTask[];
  pendingActionLabel?: string | null;
  onLogin: (username: string, password: string) => Promise<void>;
  onRegister: (username: string, password: string, betaCode: string) => Promise<void>;
  onAuthComplete?: (session: WebUserSession) => Promise<void>;
  onSessionChange?: (session: WebUserSession) => void;
  onLogout: () => void;
  onOpenWorkbench: () => void;
  onOpenCommunity: () => void;
  onDeleteProject?: (project: WebProjectSummary) => void;
  onOpenProject?: (project: WebProjectSummary) => void;
  onRemoveWork?: (task: WebGenerationPreviewTask) => void;
}

type AuthTab = "password" | "email" | "phone";
type ProfilePanel = "works" | "projects" | "assets" | "community";
type AccountPanel = "credits" | "tasks";
type ProfileDetailSelection =
  | { kind: "work"; item: WebGenerationPreviewTask }
  | { kind: "asset"; item: SavedAssetItem };

const PROFILE_LOCAL_STORAGE_PREFIX = "omniai-web-profile-ui";
const AUTH_LOGO_URL = ossAssets.brand.logo;
const AUTH_SHOWCASE_VIDEO_URL = ossAssets.auth.showcaseVideo;

function profileStorageKey(userId: string | number | undefined, field: "avatar" | "bio" | "background"): string {
  return `${PROFILE_LOCAL_STORAGE_PREFIX}:${userId ?? "guest"}:${field}`;
}

function readLocalProfileValue(userId: string | number | undefined, field: "avatar" | "bio" | "background"): string {
  if (typeof window === "undefined") return "";
  try {
    return window.localStorage.getItem(profileStorageKey(userId, field)) || "";
  } catch {
    return "";
  }
}

function writeLocalProfileValue(userId: string | number | undefined, field: "avatar" | "bio" | "background", value: string): void {
  if (typeof window === "undefined") return;
  try {
    const key = profileStorageKey(userId, field);
    if (value) {
      window.localStorage.setItem(key, value);
    } else {
      window.localStorage.removeItem(key);
    }
  } catch {
    // Local decoration should never block the account page.
  }
}

function readFileAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(String(reader.result || ""));
    reader.onerror = () => reject(reader.error || new Error("File read failed"));
    reader.readAsDataURL(file);
  });
}

function formatProfileSyncError(error: unknown, fallback: string): string {
  const raw = error instanceof Error ? error.message : String(error || "");
  const message = raw.replace(/\s+/g, " ").trim();

  if (!message) return fallback;

  if (
    /OSS PUT failed|UserDisable|AccessDenied|InvalidAccessKeyId|SignatureDoesNotMatch|<\?xml|<Error>/i.test(message)
  ) {
    return "对象存储服务拒绝上传，请检查服务器 OSS 账号或权限配置。本地预览已保留。";
  }

  if (/403|forbidden/i.test(message)) {
    return "当前账号没有上传权限，请检查登录状态或服务器权限。本地预览已保留。";
  }

  if (/413|payload too large|too large/i.test(message)) {
    return "文件过大，暂时无法上传。本地预览已保留。";
  }

  return `${fallback}：${message.slice(0, 90)}`;
}

function formatProfileLoadError(error: unknown, fallback: string): string {
  const raw = error instanceof Error ? error.message : String(error || "");
  const message = raw.replace(/\s+/g, " ").trim();

  if (!message || /^<!doctype html|<html[\s>]|<head[\s>]|<body[\s>]|^<\?xml|<Error[\s>]/i.test(message)) {
    return fallback;
  }

  if (isServerRequestError(error)) {
    if (error.status === 401 || error.status === 403) return "登录状态或权限不足，请重新登录后再试。";
    if (error.status === 404) return `${fallback}，服务端接口暂未开放或路径不存在。`;
    if (error.status && error.status >= 500) return `${fallback}，服务器暂时异常。`;
  }

  if (/not found/i.test(message)) return `${fallback}，服务端接口暂未开放或路径不存在。`;
  if (/forbidden|unauthorized/i.test(message)) return "登录状态或权限不足，请重新登录后再试。";

  return `${fallback}：${message.slice(0, 90)}`;
}

function mapAssetToSavedItem(asset: Awaited<ReturnType<typeof assetClient.list>>[number]): SavedAssetItem {
  return {
    ...asset,
    project: asset.sourceProjectId || "服务器资产库",
    version: "Server",
    ratio: String(asset.metadata?.ratio || "1:1"),
    tags: asset.tags?.length ? asset.tags : ["服务器素材"],
    thumbClass: asset.imageUrl ? "is-uploaded" : "is-station",
  };
}

function formatProfileDate(value: string | null | undefined): string {
  if (!value) return "刚刚";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;

  return new Intl.DateTimeFormat("zh-CN", {
    month: "numeric",
    day: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(date);
}

function formatTaskType(type: WebGenerationPreviewTask["type"]): string {
  const labels: Record<WebGenerationPreviewTask["type"], string> = {
    image: "图像",
    video: "视频",
    agent: "智能体",
    "digital-human": "数字人",
    "character-mix": "角色融合",
  };
  return labels[type] || type;
}

function formatTaskStatus(status: WebGenerationPreviewTask["status"]): string {
  const labels: Record<WebGenerationPreviewTask["status"], string> = {
    queued: "排队中",
    running: "生成中",
    completed: "已完成",
    failed: "失败",
  };
  return labels[status] || status;
}

function formatAssetStatus(status: string | undefined): string {
  const normalized = String(status || "").toLowerCase();
  if (normalized === "completed" || normalized === "ready" || normalized === "success") return "可用";
  if (normalized === "running" || normalized === "processing") return "处理中";
  if (normalized === "failed" || normalized === "error") return "失败";
  return status || "资产";
}

function formatAssetType(type: SavedAssetItem["type"]): string {
  const labels: Record<string, string> = {
    character: "角色",
    scene: "场景",
    prop: "道具",
    video: "视频",
    image: "图像",
    asset: "资产",
    other: "素材",
  };
  return labels[type] || "素材";
}

function ProfilePage({
  session,
  usage,
  projects,
  tasks,
  pendingActionLabel,
  onLogin,
  onRegister,
  onAuthComplete,
  onSessionChange,
  onLogout,
  onOpenWorkbench,
  onOpenCommunity,
  onDeleteProject,
  onOpenProject,
  onRemoveWork,
}: ProfilePageProps) {
  const isLoggedIn = Boolean(session);
  const userId = session?.user.id;
  const displayName = session?.user.displayName || session?.user.username || "访客账号";
  const avatarLabel = displayName.trim().slice(0, 1).toUpperCase() || "访";
  const avatarInputRef = useRef<HTMLInputElement | null>(null);
  const bannerInputRef = useRef<HTMLInputElement | null>(null);
  const [isBannerDragging, setIsBannerDragging] = useState(false);
  const [isAvatarDragging, setIsAvatarDragging] = useState(false);

  const handleBannerDragOver = (e: DragEvent) => { e.preventDefault(); if (e.dataTransfer.types.includes("Files")) setIsBannerDragging(true); };
  const handleBannerDragLeave = (e: DragEvent) => { e.preventDefault(); if (!e.currentTarget.contains(e.relatedTarget as Node)) setIsBannerDragging(false); };
  const handleBannerDrop = (e: DragEvent) => {
    e.preventDefault();
    setIsBannerDragging(false);
    if (e.dataTransfer.files.length) {
      handleBannerUpload({ target: { files: e.dataTransfer.files } } as ChangeEvent<HTMLInputElement>);
    }
  };

  const handleAvatarDragOver = (e: DragEvent) => { e.preventDefault(); if (e.dataTransfer.types.includes("Files")) setIsAvatarDragging(true); };
  const handleAvatarDragLeave = (e: DragEvent) => { e.preventDefault(); if (!e.currentTarget.contains(e.relatedTarget as Node)) setIsAvatarDragging(false); };
  const handleAvatarDrop = (e: DragEvent) => {
    e.preventDefault();
    setIsAvatarDragging(false);
    if (e.dataTransfer.files.length) {
      handleAvatarUpload({ target: { files: e.dataTransfer.files } } as ChangeEvent<HTMLInputElement>);
    }
  };

  const [mode, setMode] = useState<WebAuthMode>("login");
  const [authTab, setAuthTab] = useState<AuthTab>("password");
  const [username, setUsername] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [betaCode, setBetaCode] = useState("");
  const [phone, setPhone] = useState("");
  const [smsCode, setSmsCode] = useState("");
  const [notice, setNotice] = useState<string | null>(null);
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [smsCooldown, setSmsCooldown] = useState(0);
  const [isSendingSms, setIsSendingSms] = useState(false);
  const [emailCode, setEmailCode] = useState("");
  const [emailCooldown, setEmailCooldown] = useState(0);
  const [isSendingEmail, setIsSendingEmail] = useState(false);
  const [showForgotPassword, setShowForgotPassword] = useState(false);
  const [forgotStep, setForgotStep] = useState<"email" | "code" | "newPassword">("email");
  const [forgotEmail, setForgotEmail] = useState("");
  const [forgotCode, setForgotCode] = useState("");
  const [forgotPassword, setForgotPassword] = useState("");

  const [activePanel, setActivePanel] = useState<ProfilePanel>("works");
  const [accountPanel, setAccountPanel] = useState<AccountPanel>("credits");
  const [savedAssets, setSavedAssets] = useState<SavedAssetItem[]>([]);
  const [assetNotice, setAssetNotice] = useState<string | null>(null);
  const [communityCases, setCommunityCases] = useState<ServerCommunityCase[]>([]);
  const [communityNotice, setCommunityNotice] = useState<string | null>(null);
  const [profileNotice, setProfileNotice] = useState<string | null>(null);
  const [localAvatarUrl, setLocalAvatarUrl] = useState(() => session?.user.avatarUrl || readLocalProfileValue(userId, "avatar"));
  const [profileBio, setProfileBio] = useState(() => session?.user.bio || readLocalProfileValue(userId, "bio"));
  const [isBioEditing, setIsBioEditing] = useState(false);
  const [bioEditBackup, setBioEditBackup] = useState("");
  const [bioStatusNotice, setBioStatusNotice] = useState<string | null>(null);
  const [bannerUrl, setBannerUrl] = useState(() => session?.user.backgroundUrl || readLocalProfileValue(userId, "background"));
  const [detailSelection, setDetailSelection] = useState<ProfileDetailSelection | null>(null);
  const [detailNotice, setDetailNotice] = useState<string | null>(null);
  const [isDeletingDetail, setIsDeletingDetail] = useState(false);
  const [isDownloadingDetail, setIsDownloadingDetail] = useState(false);

  const completedTasks = useMemo(
    () => tasks.filter((task) => task.status === "completed"),
    [tasks],
  );
  const visibleWorks = useMemo(
    () => (completedTasks.length ? completedTasks : tasks.slice(0, 6)),
    [completedTasks, tasks],
  );
  const totalBalance = usage.balanceCents + (session?.user.enterpriseBalanceCents || 0);
  const packageLabel = session?.user.activePackages?.[0]?.name || "按量积分";
  const avatarUrl = session?.user.avatarUrl || localAvatarUrl || null;
  const displayedBio = profileBio.trim() || "这个人还没有填写个性签名";
  const activePanelTitle =
    activePanel === "works"
      ? "代表作"
      : activePanel === "projects"
        ? "服务器项目"
        : activePanel === "assets"
          ? "我的资产"
          : "社区审核";
  const activePanelDescription =
    activePanel === "works"
      ? "最近完成的高质量生成内容"
      : activePanel === "projects"
        ? "云端同步的创作项目"
        : activePanel === "assets"
          ? "可复用的图片、视频与素材"
          : "已提交社区的案例状态";
  const activePanelCount =
    activePanel === "works"
      ? visibleWorks.length
      : activePanel === "projects"
        ? projects.length
        : activePanel === "assets"
          ? savedAssets.length
          : communityCases.length;
  const emailLooksValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
  const phoneLooksValid = /^1[3-9]\d{9}$/.test(phone.trim());
  const passwordLooksReady = password.length >= (mode === "register" ? 6 : 1);

  useEffect(() => {
    setLocalAvatarUrl(session?.user.avatarUrl || readLocalProfileValue(userId, "avatar"));
    setProfileBio(session?.user.bio || readLocalProfileValue(userId, "bio"));
    setBannerUrl(session?.user.backgroundUrl || readLocalProfileValue(userId, "background"));
  }, [session?.user.avatarUrl, session?.user.backgroundUrl, session?.user.bio, userId]);

  useEffect(() => {
    if (!session) return;

    setCommunityNotice(null);
    setAssetNotice(null);
    let cancelled = false;
    void Promise.allSettled([assetClient.list(), communityClient.listMyCases()]).then((results) => {
      if (cancelled) return;

      const [assetResult, communityResult] = results;
      if (assetResult.status === "fulfilled") {
        setSavedAssets(assetResult.value.map(mapAssetToSavedItem));
      } else {
        setSavedAssets([]);
        setAssetNotice(formatProfileLoadError(assetResult.reason, "资产记录暂时不可用"));
      }

      if (communityResult.status === "fulfilled") {
        setCommunityCases(communityResult.value);
      } else {
        setCommunityCases([]);
        setCommunityNotice(formatProfileLoadError(communityResult.reason, "社区记录暂时不可用"));
      }
    });

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

  useEffect(() => {
    if (!session || activePanel !== "assets") return;

    setAssetNotice(null);
    assetClient
      .list()
      .then((items) => setSavedAssets(items.map(mapAssetToSavedItem)))
      .catch((error) => {
        setSavedAssets([]);
        setAssetNotice(formatProfileLoadError(error, "资产记录暂时不可用"));
      });
  }, [activePanel, session]);

  useEffect(() => {
    if (smsCooldown <= 0) return;
    const timer = window.setInterval(() => {
      setSmsCooldown((current) => Math.max(0, current - 1));
    }, 1000);
    return () => window.clearInterval(timer);
  }, [smsCooldown]);

  useEffect(() => {
    if (emailCooldown <= 0) return;
    const timer = window.setInterval(() => {
      setEmailCooldown((current) => Math.max(0, current - 1));
    }, 1000);
    return () => window.clearInterval(timer);
  }, [emailCooldown]);

  const handleSendEmailCode = async (purpose: "register" | "login" | "reset" = "register") => {
    const targetEmail = purpose === "reset" ? forgotEmail : email;
    if (emailCooldown > 0 || !targetEmail.trim() || isSendingEmail) return;
    if (purpose === "register" && !betaCode.trim()) {
      setNotice("请输入企业邀请码 / 内测码后再获取验证码");
      return;
    }
    setIsSendingEmail(true);
    setNotice(null);
    try {
      const result = await keyServerClient.sendEmailCode(targetEmail, purpose, betaCode);
      setEmailCooldown(result.cooldownSeconds || 60);
      if (result.devCode) {
        setNotice(`验证码已发送（开发模式: ${result.devCode}）`);
      } else {
        setNotice("验证码已发送，请查收邮件");
      }
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "验证码发送失败");
    } finally {
      setIsSendingEmail(false);
    }
  };

  const handleForgotPassword = async () => {
    if (forgotStep === "email") {
      if (!forgotEmail.trim()) { setNotice("请输入邮箱"); return; }
      try {
        await keyServerClient.forgotPassword({ email: forgotEmail });
        setForgotStep("code");
        setNotice("重置验证码已发送到您的邮箱");
        await handleSendEmailCode("reset");
      } catch (error) {
        setNotice(error instanceof Error ? error.message : "发送失败");
      }
    } else if (forgotStep === "code") {
      if (!forgotCode.trim()) { setNotice("请输入验证码"); return; }
      setForgotStep("newPassword");
      setNotice(null);
    } else {
      if (forgotPassword.length < 6) { setNotice("密码至少 6 位"); return; }
      try {
        const result = await keyServerClient.resetPassword({ email: forgotEmail, code: forgotCode, newPassword: forgotPassword });
        setNotice(result.message || "密码重置成功，请重新登录");
        setShowForgotPassword(false);
        setForgotStep("email");
        setForgotEmail("");
        setForgotCode("");
        setForgotPassword("");
        setMode("login");
      } catch (error) {
        setNotice(error instanceof Error ? error.message : "重置失败");
      }
    }
  };

  const handleSendSms = async () => {
    if (smsCooldown > 0 || !phone.trim() || isSendingSms) return;
    if (mode === "register" && !betaCode.trim()) {
      setNotice("请输入企业邀请码 / 内测码后再获取验证码");
      return;
    }
    setIsSendingSms(true);
    setNotice(null);
    try {
      const result = await keyServerClient.sendSmsCode(phone, mode === "login" ? "login" : "register", betaCode);
      setSmsCooldown(result.cooldownSeconds || 60);
      setNotice("验证码已发送，请查收短信");
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "验证码发送失败");
    } finally {
      setIsSendingSms(false);
    }
  };

  const validateField = (field: string, value: string): string => {
    switch (field) {
      case "username":
        if (!value.trim()) return "请输入用户名";
        if (mode === "register" && value.trim().length < 2) return "用户名至少 2 个字符";
        return "";
      case "password":
        if (!value) return "请输入密码";
        if (mode === "register" && value.length < 6) return "密码至少 6 位";
        return "";
      case "email":
        if (!value.trim()) return "请输入邮箱";
        if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) return "邮箱格式不正确";
        return "";
      case "phone":
        if (!value.trim()) return "请输入手机号";
        if (!/^1[3-9]\d{9}$/.test(value)) return "手机号格式不正确";
        return "";
      case "betaCode":
        if (!value.trim()) return "请输入邀请码";
        return "";
      case "smsCode":
        if (!value.trim()) return "请输入验证码";
        if (value.length !== 6) return "验证码为 6 位数字";
        return "";
      case "emailCode":
        if (!value.trim()) return "请输入邮箱验证码";
        if (value.length !== 6) return "验证码为 6 位数字";
        return "";
      default:
        return "";
    }
  };

  const handleFieldBlur = (field: string, value: string) => {
    const error = validateField(field, value);
    setFieldErrors((prev) => ({ ...prev, [field]: error }));
  };

  const clearFieldError = (field: string) => {
    if (fieldErrors[field]) {
      setFieldErrors((prev) => ({ ...prev, [field]: "" }));
    }
  };

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (isSubmitting) return;

    const errors: Record<string, string> = {};
    if (mode === "register") {
      const betaErr = validateField("betaCode", betaCode);
      if (betaErr) errors.betaCode = betaErr;
    }
    if (authTab === "phone") {
      const phoneErr = validateField("phone", phone);
      if (phoneErr) errors.phone = phoneErr;
      const smsErr = validateField("smsCode", smsCode);
      if (smsErr) errors.smsCode = smsErr;
      if (mode === "register") {
        const pwErr = validateField("password", password);
        if (pwErr) errors.password = pwErr;
      }
    } else if (authTab === "email") {
      const emailErr = validateField("email", email);
      if (emailErr) errors.email = emailErr;
      const pwErr = validateField("password", password);
      if (pwErr) errors.password = pwErr;
      if (mode === "register") {
        const codeErr = validateField("emailCode", emailCode);
        if (codeErr) errors.emailCode = codeErr;
      }
    } else {
      const userErr = validateField("username", username);
      if (userErr) errors.username = userErr;
      const pwErr = validateField("password", password);
      if (pwErr) errors.password = pwErr;
    }

    if (Object.values(errors).some(Boolean)) {
      setFieldErrors(errors);
      return;
    }

    setIsSubmitting(true);
    setNotice(null);

    try {
      if (authTab === "phone") {
        const nextSession =
          mode === "login"
            ? await keyServerClient.loginPhone({ phone, code: smsCode })
            : await keyServerClient.registerPhone({ phone, code: smsCode, password, betaCode });
        await onAuthComplete?.(nextSession);
      } else if (authTab === "email") {
        const nextSession =
          mode === "login"
            ? await keyServerClient.loginEmail({ email, password })
            : await keyServerClient.registerEmail({ email, password, code: emailCode, username: username.trim() || undefined, betaCode });
        await onAuthComplete?.(nextSession);
      } else if (mode === "login") {
        await onLogin(username.trim(), password);
      } else {
        await onRegister(username.trim(), password, betaCode);
      }
    } catch (error) {
      setNotice(error instanceof Error ? error.message : "操作失败，请稍后重试");
    } finally {
      setIsSubmitting(false);
    }
  };

  const updateProfileUser = (patch: Partial<WebUserSession["user"]>) => {
    if (!session) return;
    const nextUser = { ...session.user, ...patch };
    const nextSession = keyServerClient.updateStoredSessionUser(nextUser) || { ...session, user: nextUser };
    onSessionChange?.(nextSession);
  };

  const syncProfilePatch = async (patch: Parameters<typeof keyServerClient.updateProfile>[0]) => {
    if (!session) return;
    try {
      const user = await keyServerClient.updateProfile(patch);
      updateProfileUser(user);
      setProfileNotice(null);
    } catch (error) {
      setProfileNotice(formatProfileSyncError(error, "个人资料同步失败"));
    }
  };

  const handleAvatarUpload = async (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file || !file.type.startsWith("image/")) return;

    const dataUrl = await readFileAsDataUrl(file);
    try {
      const uploaded = await aiGenerationClient.uploadAsset({
        dataUrl,
        name: file.name,
        mimeType: file.type,
        scope: "profile-avatar",
      });
      const nextUrl = uploaded.url || dataUrl;
      setLocalAvatarUrl(nextUrl);
      writeLocalProfileValue(userId, "avatar", nextUrl);
      updateProfileUser({ avatarUrl: nextUrl });
      await syncProfilePatch({ avatarOssKey: uploaded.ossKey || null, avatarUrl: uploaded.url || nextUrl });
    } catch (error) {
      setLocalAvatarUrl(dataUrl);
      writeLocalProfileValue(userId, "avatar", dataUrl);
      updateProfileUser({ avatarUrl: dataUrl });
      setProfileNotice(formatProfileSyncError(error, "头像上传失败，已先在本地预览"));
    }
  };

  const handleBannerUpload = async (event: ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file || !file.type.startsWith("image/")) return;

    const dataUrl = await readFileAsDataUrl(file);
    try {
      const uploaded = await aiGenerationClient.uploadAsset({
        dataUrl,
        name: file.name,
        mimeType: file.type,
        scope: "profile-background",
      });
      const nextUrl = uploaded.url || dataUrl;
      setBannerUrl(nextUrl);
      writeLocalProfileValue(userId, "background", nextUrl);
      updateProfileUser({ backgroundUrl: nextUrl });
      await syncProfilePatch({ backgroundUrl: nextUrl, profileBackgroundUrl: nextUrl });
    } catch (error) {
      setBannerUrl(dataUrl);
      writeLocalProfileValue(userId, "background", dataUrl);
      updateProfileUser({ backgroundUrl: dataUrl });
      setProfileNotice(formatProfileSyncError(error, "背景上传失败，已先在本地预览"));
    }
  };

  const handleBioBlur = () => {
    const nextBio = profileBio.trim();
    writeLocalProfileValue(userId, "bio", nextBio);
    updateProfileUser({ bio: nextBio || null });
    void syncProfilePatch({ bio: nextBio || null });
  };

  const startBioEdit = () => {
    setBioEditBackup(profileBio);
    setBioStatusNotice(null);
    setIsBioEditing(true);
  };

  const confirmBioEdit = () => {
    handleBioBlur();
    setIsBioEditing(false);
    setBioStatusNotice("个性签名已保存");
  };

  const cancelBioEdit = () => {
    setProfileBio(bioEditBackup);
    setIsBioEditing(false);
    setBioStatusNotice(null);
  };

  const handleInteractiveCardKeyDown = (event: KeyboardEvent<HTMLElement>, action: () => void) => {
    if (event.target !== event.currentTarget) return;
    if (event.key !== "Enter" && event.key !== " ") return;
    event.preventDefault();
    action();
  };

  const openDetailSelection = (selection: ProfileDetailSelection) => {
    setDetailNotice(null);
    setIsDeletingDetail(false);
    setIsDownloadingDetail(false);
    setDetailSelection(selection);
  };

  const closeDetailSelection = () => {
    if (isDeletingDetail || isDownloadingDetail) return;
    setDetailSelection(null);
    setDetailNotice(null);
  };

  useEffect(() => {
    if (!detailSelection) return undefined;
    const handleKeyDown = (event: globalThis.KeyboardEvent) => {
      if (event.key === "Escape") closeDetailSelection();
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [detailSelection, isDeletingDetail, isDownloadingDetail]);

  useEffect(() => {
    if (!detailSelection || typeof document === "undefined") return undefined;

    const { body, documentElement } = document;
    const previousBodyOverflow = body.style.overflow;
    const previousRootOverscroll = documentElement.style.overscrollBehavior;

    body.style.overflow = "hidden";
    documentElement.style.overscrollBehavior = "contain";

    return () => {
      body.style.overflow = previousBodyOverflow;
      documentElement.style.overscrollBehavior = previousRootOverscroll;
    };
  }, [detailSelection]);

  const handleDownloadSelectedDetail = async () => {
    if (!detailSelection || isDownloadingDetail) return;

    const url =
      detailSelection.kind === "work"
        ? detailSelection.item.outputUrl
        : detailSelection.item.imageUrl || detailSelection.item.url || "";
    if (!url) {
      setDetailNotice("暂无可下载的媒体文件");
      return;
    }

    const isVideo =
      detailSelection.kind === "work"
        ? detailSelection.item.type === "video"
        : detailSelection.item.type === "video" || /\.(mp4|webm|mov|m4v)(\?|#|$)/i.test(url);
    const taskId = detailSelection.kind === "work" ? detailSelection.item.id : detailSelection.item.sourceTaskId || undefined;
    const name = detailSelection.kind === "work" ? detailSelection.item.title : detailSelection.item.name;

    setIsDownloadingDetail(true);
    setDetailNotice("正在准备下载...");
    try {
      const status = await downloadResultAsset(url, name, isVideo, taskId);
      setDetailNotice(status === "saved" ? "已保存到本地" : "已开始保存到本地");
    } catch (error) {
      if (error instanceof DOMException && error.name === "AbortError") {
        setDetailNotice("已取消下载");
      } else {
        setDetailNotice(error instanceof Error ? error.message : "下载失败，请稍后重试");
      }
    } finally {
      setIsDownloadingDetail(false);
    }
  };

  const handleDeleteSelectedDetail = async () => {
    if (!detailSelection || isDeletingDetail) return;

    if (detailSelection.kind === "work") {
      onRemoveWork?.(detailSelection.item);
      setDetailNotice("已从当前代表作列表移除");
      setDetailSelection(null);
      return;
    }

    setIsDeletingDetail(true);
    setDetailNotice(null);
    try {
      await assetClient.delete(detailSelection.item.id, { cleanupUserData: true });
      setSavedAssets((current) => current.filter((asset) => asset.id !== detailSelection.item.id));
      setDetailSelection(null);
      setAssetNotice(`已删除 ${detailSelection.item.name}`);
    } catch (error) {
      setDetailNotice(formatProfileLoadError(error, "资产删除失败"));
    } finally {
      setIsDeletingDetail(false);
    }
  };

  const renderDetailMedia = (url: string | null | undefined, type: "image" | "video" | "asset") => {
    const mediaUrl = typeof url === "string" ? url.trim() : "";
    const isVideoPreview = type === "video" || /\.(mp4|webm|mov|m4v)(\?|#|$)/i.test(mediaUrl);

    if (!mediaUrl) {
      return (
        <div className="profile-page__detail-placeholder">
          {type === "video" ? <PlayCircleOutlined /> : <FileImageOutlined />}
          <span>暂无可预览内容</span>
        </div>
      );
    }

    return isVideoPreview ? (
      <video className="profile-page__detail-media" src={mediaUrl} controls playsInline />
    ) : (
      <img className="profile-page__detail-media" src={mediaUrl} alt="" />
    );
  };

  const renderDetailModal = () => {
    if (!detailSelection) return null;
    const modalTarget = typeof document === "undefined" ? null : document.querySelector(".web-shell") || document.body;
    if (!modalTarget) return null;

    const isWork = detailSelection.kind === "work";
    const title = isWork ? detailSelection.item.title : detailSelection.item.name;
    const description = isWork ? detailSelection.item.prompt : detailSelection.item.description;
    const mediaUrl = isWork ? detailSelection.item.outputUrl : detailSelection.item.imageUrl || detailSelection.item.url;
    const mediaType = isWork
      ? detailSelection.item.type === "video" ? "video" : "image"
      : detailSelection.item.type === "video" ? "video" : "asset";

    return createPortal(
      <div className="profile-page__detail-overlay" role="dialog" aria-modal="true" aria-labelledby="profile-detail-title">
        <button type="button" className="profile-page__detail-backdrop" aria-label="关闭详情" onClick={closeDetailSelection} />
        <section className="profile-page__detail-panel">
          <header className="profile-page__detail-head">
            <div>
              <span className="profile-page__detail-eyebrow">{isWork ? "代表作详情" : "资产详情"}</span>
              <h2 id="profile-detail-title">{title}</h2>
            </div>
            <button type="button" className="profile-page__detail-close" aria-label="关闭详情" onClick={closeDetailSelection}>
              <CloseOutlined />
            </button>
          </header>

          <div className="profile-page__detail-body">
            <div className="profile-page__detail-preview">
              {renderDetailMedia(mediaUrl, mediaType)}
            </div>
            <div className="profile-page__detail-info">
              <p>{description || "暂无描述"}</p>
              <dl>
                <div>
                  <dt>{isWork ? "类型" : "资产类型"}</dt>
                  <dd>{isWork ? formatTaskType(detailSelection.item.type) : formatAssetType(detailSelection.item.type)}</dd>
                </div>
                <div>
                  <dt>状态</dt>
                  <dd>{isWork ? formatTaskStatus(detailSelection.item.status) : formatAssetStatus(detailSelection.item.status)}</dd>
                </div>
                <div>
                  <dt>{isWork ? "创建时间" : "更新时间"}</dt>
                  <dd>{formatProfileDate(isWork ? detailSelection.item.createdAt : detailSelection.item.updatedAt)}</dd>
                </div>
                {!isWork ? (
                  <div>
                    <dt>标签</dt>
                    <dd>{detailSelection.item.tags?.length ? detailSelection.item.tags.join(" / ") : "服务器素材"}</dd>
                  </div>
                ) : null}
              </dl>
              {detailNotice ? <span className="profile-page__detail-notice">{detailNotice}</span> : null}
            </div>
          </div>

          <footer className="profile-page__detail-actions">
            <button
              type="button"
              className="profile-page__detail-action profile-page__detail-action--primary"
              onClick={() => void handleDownloadSelectedDetail()}
              disabled={isDownloadingDetail}
            >
              <DownloadOutlined />
              {isDownloadingDetail ? "下载中..." : "下载"}
            </button>
            <button type="button" className="profile-page__detail-action profile-page__detail-action--secondary" onClick={onOpenWorkbench}>
              <EditOutlined />
              {isWork ? "继续编辑" : "使用素材"}
            </button>
            <button
              type="button"
              className="profile-page__detail-action profile-page__detail-action--danger"
              onClick={() => void handleDeleteSelectedDetail()}
              disabled={isDeletingDetail}
            >
              <DeleteOutlined />
              {isDeletingDetail ? "删除中..." : isWork ? "移除代表作" : "删除资产"}
            </button>
          </footer>
        </section>
      </div>,
      modalTarget,
    );
  };

  const renderEmptyState = (text: string, actionLabel: string, action: () => void) => (
    <div className="profile-page__empty-state">
      <span className="profile-page__empty-mark" aria-hidden="true">
        <PlusOutlined />
      </span>
      <p className="profile-page__empty-text">{text}</p>
      <button type="button" className="profile-page__empty-btn" onClick={action}>
        <PlusOutlined />
        {actionLabel}
      </button>
    </div>
  );

  const renderCardPreview = (
    url: string | null | undefined,
    type: "image" | "video" | "project" | "asset",
    label: string,
  ) => {
    const mediaUrl = typeof url === "string" ? url.trim() : "";
    const isVideoPreview = type === "video" || /\.(mp4|webm|mov)(\?|#|$)/i.test(mediaUrl);
    const placeholderIcon =
      type === "video" ? <PlayCircleOutlined /> : type === "project" ? <FolderOpenOutlined /> : <FileImageOutlined />;

    return (
      <div className={`profile-page__list-card-preview${mediaUrl ? " has-media" : ""}`} aria-hidden="true">
        {mediaUrl ? (
          isVideoPreview ? (
            <video src={mediaUrl} muted playsInline preload="metadata" />
          ) : (
            <img src={mediaUrl} alt="" loading="lazy" />
          )
        ) : (
          <span className="profile-page__list-card-placeholder">{placeholderIcon}</span>
        )}
        <span className="profile-page__media-badge">{label}</span>
      </div>
    );
  };

  const renderActivePanel = () => {
    if (activePanel === "works") {
      return visibleWorks.length ? (
        <div className="profile-page__works-scroll">
          <div className="profile-page__list-grid motion-stagger">
            {visibleWorks.map((task) => (
              <article
                key={task.id}
                className="profile-page__list-card profile-page__media-card profile-page__interactive-card"
                role="button"
                tabIndex={0}
                aria-label={`查看代表作 ${task.title}`}
                onClick={() => openDetailSelection({ kind: "work", item: task })}
                onKeyDown={(event) => handleInteractiveCardKeyDown(event, () => openDetailSelection({ kind: "work", item: task }))}
              >
                {renderCardPreview(task.outputUrl, task.type === "video" ? "video" : "image", formatTaskType(task.type))}
                <div className="profile-page__list-card-body">
                  <div className="profile-page__list-card-head">
                    <strong>{task.title}</strong>
                  </div>
                  <p>{task.prompt}</p>
                  <div className="profile-page__list-card-meta">
                    <span>{formatTaskStatus(task.status)}</span>
                    <span>{formatProfileDate(task.createdAt)}</span>
                  </div>
                </div>
              </article>
            ))}
          </div>
        </div>
      ) : (
        renderEmptyState("向全世界展示你最得意的创作。", "开始创作", onOpenWorkbench)
      );
    }

    if (activePanel === "projects") {
      return projects.length ? (
        <div className="profile-page__list-grid motion-stagger">
          {projects.map((project) => (
            <article
              key={project.id}
              className="profile-page__list-card profile-page__media-card profile-page__interactive-card"
              role="button"
              tabIndex={0}
              aria-label={`打开项目 ${project.name}`}
              onClick={() => (onOpenProject ? onOpenProject(project) : onOpenWorkbench())}
              onKeyDown={(event) =>
                handleInteractiveCardKeyDown(event, () => (onOpenProject ? onOpenProject(project) : onOpenWorkbench()))
              }
            >
              {renderCardPreview(project.thumbnailUrl, "project", "项目")}
              <div className="profile-page__list-card-body">
                <div className="profile-page__list-card-head">
                  <strong>{project.name}</strong>
                  {onDeleteProject ? (
                    <button
                      type="button"
                      className="profile-page__delete-project"
                      aria-label={`删除项目 ${project.name}`}
                      onClick={(event) => {
                        event.stopPropagation();
                        onDeleteProject(project);
                      }}
                    >
                      <DeleteOutlined />
                    </button>
                  ) : null}
                </div>
                <p>{project.description || "最近更新的项目"}</p>
                <div className="profile-page__list-card-meta">
                  <span>{project.storyboardCount} 节点</span>
                  <span>{formatProfileDate(project.updatedAt)}</span>
                </div>
              </div>
            </article>
          ))}
        </div>
      ) : (
        renderEmptyState("还没有同步到服务器的项目。", "进入工作台", onOpenWorkbench)
      );
    }

    if (activePanel === "assets") {
      return savedAssets.length ? (
        <div className="profile-page__list-grid">
          {savedAssets.map((asset) => (
            <article
              key={asset.id}
              className="profile-page__list-card profile-page__media-card profile-page__interactive-card"
              role="button"
              tabIndex={0}
              aria-label={`查看资产 ${asset.name}`}
              onClick={() => openDetailSelection({ kind: "asset", item: asset })}
              onKeyDown={(event) => handleInteractiveCardKeyDown(event, () => openDetailSelection({ kind: "asset", item: asset }))}
            >
              {renderCardPreview(asset.imageUrl || asset.url, asset.type === "video" ? "video" : "asset", formatAssetType(asset.type))}
              <div className="profile-page__list-card-body">
                <div className="profile-page__list-card-head">
                  <strong>{asset.name}</strong>
                  <span>{formatAssetStatus(asset.status)}</span>
                </div>
                <p>{asset.description}</p>
                <div className="profile-page__list-card-meta">
                  <span>{formatAssetType(asset.type)}</span>
                  <span>{formatProfileDate(asset.updatedAt)}</span>
                </div>
              </div>
            </article>
          ))}
        </div>
      ) : (
        renderEmptyState(assetNotice || "服务器资产库暂无内容。", "去工作台生成", onOpenWorkbench)
      );
    }

    return communityCases.length ? (
      <div className="profile-page__review-list">
        {communityCases.map((item) => (
          <div key={item.id} className="profile-page__review-item">
            {item.coverUrl ? <img src={item.coverUrl} alt="" /> : <span className="profile-page__review-thumb" />}
            <div>
              <strong>{item.title}</strong>
              <span>
                {item.status === "approved" ? "已通过" : item.status === "rejected" ? "未通过" : "审核中"}
              </span>
              <small>{item.copyCount} 次复用</small>
            </div>
          </div>
        ))}
      </div>
    ) : (
      renderEmptyState(communityNotice || "还没有发布到社区的内容。", "去社区发布", onOpenCommunity)
    );
  };

  if (isLoggedIn) {
    return (
      <section className="profile-page profile-page--dashboard page-motion">
        <input ref={avatarInputRef} type="file" accept="image/*" hidden onChange={(event) => void handleAvatarUpload(event)} />
        <input ref={bannerInputRef} type="file" accept="image/*" hidden onChange={(event) => void handleBannerUpload(event)} />
        <header
          className={`profile-page__banner${bannerUrl ? " has-image" : ""}${isBannerDragging ? " is-dragging" : ""}`}
          style={bannerUrl ? { backgroundImage: `url(${bannerUrl})` } : undefined}
          onDragOver={handleBannerDragOver}
          onDragLeave={handleBannerDragLeave}
          onDrop={handleBannerDrop}
        >
          <button type="button" className="profile-page__banner-btn" onClick={() => bannerInputRef.current?.click()} aria-label="更换背景">
            <CameraOutlined />
            <span className="profile-page__banner-btn-label">更换背景</span>
          </button>
          <div className="profile-page__banner-overlay" />
        </header>

        <div className="profile-page__body">
          <aside className="profile-page__sidebar">
            <div className="profile-page__sidebar-head">
              <div className={`profile-page__avatar-ring${isAvatarDragging ? " is-dragging" : ""}`}>
                {avatarUrl ? (
                  <img className="profile-page__avatar" src={avatarUrl} alt="" />
                ) : (
                  <span className="profile-page__avatar">{avatarLabel}</span>
                )}
                <button
                  type="button"
                  className="profile-page__avatar-edit"
                  onClick={() => avatarInputRef.current?.click()}
                  onDragOver={handleAvatarDragOver}
                  onDragLeave={handleAvatarDragLeave}
                  onDrop={handleAvatarDrop}
                  aria-label="更换头像"
                >
                  <CameraOutlined />
                </button>
                <span className="profile-page__avatar-badge">
                  <CheckCircleFilled />
                </span>
              </div>
              <strong className="profile-page__username">{displayName}</strong>
              {isBioEditing ? (
                <div className="profile-page__bio-editor">
                  <textarea
                    className="profile-page__bio"
                    value={profileBio}
                    onChange={(event) => setProfileBio(event.target.value)}
                    placeholder="填写一句个人签名"
                    rows={2}
                    maxLength={80}
                    autoFocus
                  />
                  <div className="profile-page__bio-actions">
                    <button type="button" className="profile-page__bio-action profile-page__bio-action--save" onClick={confirmBioEdit}>
                      <CheckOutlined />
                      保存
                    </button>
                    <button type="button" className="profile-page__bio-action" onClick={cancelBioEdit}>
                      <CloseOutlined />
                      取消
                    </button>
                  </div>
                </div>
              ) : (
                <button
                  type="button"
                  className={`profile-page__bio-display${profileBio.trim() ? "" : " is-empty"}`}
                  onClick={startBioEdit}
                >
                  <span>{displayedBio}</span>
                  <EditOutlined className="profile-page__bio-edit-icon" />
                </button>
              )}
              {bioStatusNotice ? <span className="profile-page__bio-status">{bioStatusNotice}</span> : null}
              {profileNotice ? <span className="profile-page__sync-notice">{profileNotice}</span> : null}
            </div>

            <div className="profile-page__counts">
              <div className="profile-page__count">
                <strong>{projects.length}</strong>
                <span>项目</span>
              </div>
              <div className="profile-page__count">
                <strong>{completedTasks.length}</strong>
                <span>作品</span>
              </div>
              <div className="profile-page__count">
                <strong>{savedAssets.length}</strong>
                <span>资产</span>
              </div>
            </div>

            <div className="profile-page__account-card">
              <div className="profile-page__list-tabs">
                <button
                  type="button"
                  className={accountPanel === "credits" ? "is-active" : ""}
                  onClick={() => setAccountPanel("credits")}
                >
                  <span>可用积分</span>
                  <strong>{(totalBalance / 100).toFixed(2)}</strong>
                </button>
                <button
                  type="button"
                  className={accountPanel === "tasks" ? "is-active" : ""}
                  onClick={() => setAccountPanel("tasks")}
                >
                  <span>生成任务</span>
                  <strong>{tasks.length}</strong>
                </button>
              </div>
              <div className="profile-page__account-summary">
                {accountPanel === "credits" ? (
                  <>
                    <span className="profile-page__account-summary-main">
                      <small>当前账号</small>
                      <strong>{displayName}</strong>
                      <em>{packageLabel}</em>
                    </span>
                    <span className="profile-page__account-summary-metric">
                      <small>积分剩余</small>
                      <strong>{(usage.balanceCents / 100).toFixed(2)}</strong>
                    </span>
                  </>
                ) : (
                  <>
                    <span className="profile-page__account-summary-main">
                      <small>任务概览</small>
                      <strong>{tasks.length} 个任务</strong>
                      <em>{completedTasks.length} 个已完成</em>
                    </span>
                    <span className="profile-page__account-summary-metric">
                      <small>已完成</small>
                      <strong>{completedTasks.length}</strong>
                    </span>
                  </>
                )}
              </div>
            </div>

            <div className="profile-page__actions">
              <button type="button" className="profile-page__share-btn profile-page__share-btn--plan">
                <ShareAltOutlined />
                {packageLabel}
              </button>

              <button type="button" className="profile-page__share-btn profile-page__share-btn--primary" onClick={onOpenWorkbench}>
                <PlusOutlined />
                进入工作台
              </button>
              <button type="button" className="profile-page__share-btn profile-page__share-btn--secondary" onClick={onOpenCommunity}>
                <ShareAltOutlined />
                打开社区
              </button>
              <button type="button" className="profile-page__share-btn profile-page__share-btn--danger" onClick={onLogout}>
                <LockOutlined />
                退出登录
              </button>
            </div>
          </aside>

          <main className="profile-page__main">
            <div className="profile-page__main-tabs">
              <button type="button" className={activePanel === "works" ? "is-active" : ""} onClick={() => setActivePanel("works")}>
                <span>我的作品</span>
              </button>
              <button type="button" className={activePanel === "projects" ? "is-active" : ""} onClick={() => setActivePanel("projects")}>
                <span>我的项目</span>
              </button>
              <button type="button" className={activePanel === "assets" ? "is-active" : ""} onClick={() => setActivePanel("assets")}>
                <span>我的资产</span>
              </button>
              <button type="button" className={activePanel === "community" ? "is-active" : ""} onClick={() => setActivePanel("community")}>
                <span>社区发布</span>
              </button>
            </div>

            <div className="profile-page__section">
              <div className="profile-page__section-head">
                <span className="profile-page__section-label">{activePanelTitle}</span>
                <span className="profile-page__section-desc">{activePanelDescription}</span>
                <span className="profile-page__section-meta">{activePanelCount} 项</span>
              </div>
              {renderActivePanel()}
            </div>
          </main>
        </div>
        {renderDetailModal()}
      </section>
    );
  }

  return (
    <section className="auth-page page-motion">
      <div className="auth-page__showcase">
        <div className="auth-page__video-wrap">
          <video className="auth-page__video" autoPlay muted loop playsInline poster="">
            <source src={AUTH_SHOWCASE_VIDEO_URL} type="video/mp4" />
          </video>
          <div className="auth-page__video-overlay">
            <div className="auth-page__showcase-content">
              <div className="auth-page__brand-row">
                <h1 className="auth-page__brand">OmniAI</h1>
              </div>
              <p className="auth-page__tagline">一句话，从创意到成片</p>
              <div className="auth-page__features">
                <span>AI 视频生成</span>
                <span>AI 图片创作</span>
                <span>AI 电商素材</span>
              </div>
              <div className="auth-page__showcase-stats" aria-label="平台能力">
                <span>
                  <strong>Studio</strong>
                  创作工作台
                </span>
                <span>
                  <strong>Assets</strong>
                  资产沉淀
                </span>
                <span>
                  <strong>Team</strong>
                  团队协作
                </span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <aside className="auth-page__form-panel">
        <div className="auth-page__form-inner">
          <div className="auth-page__form-head">
            <span className="auth-page__logo">
              <img src={AUTH_LOGO_URL} alt="OmniAI" />
            </span>
            <h2 className="auth-page__title">{mode === "login" ? "欢迎回来" : "创建账号"}</h2>
            <p className="auth-page__subtitle">
              {mode === "login" ? "登录后继续你的 AI 创作之旅" : "注册即可免费体验全部功能"}
            </p>
          </div>

          <div className="auth-page__mode-tabs">
            <button
              type="button"
              className={mode === "login" ? "is-active" : ""}
              onClick={() => {
                setMode("login");
                setNotice(null);
                setFieldErrors({});
              }}
            >
              登录
            </button>
            <button
              type="button"
              className={mode === "register" ? "is-active" : ""}
              onClick={() => {
                setMode("register");
                setNotice(null);
                setFieldErrors({});
              }}
            >
              注册
            </button>
          </div>

          <div className="auth-page__auth-tabs">
            <button type="button" className={authTab === "password" ? "is-active" : ""} onClick={() => { setAuthTab("password"); setFieldErrors({}); }}>
              <UserOutlined /> 账号密码
            </button>
            <button type="button" className={authTab === "email" ? "is-active" : ""} onClick={() => { setAuthTab("email"); setFieldErrors({}); }}>
              <MailOutlined /> 邮箱
            </button>
            <button type="button" className={authTab === "phone" ? "is-active" : ""} onClick={() => { setAuthTab("phone"); setFieldErrors({}); }}>
              <MobileOutlined />
              <span className="auth-page__tab-label-short">手机</span>
            </button>
          </div>

          {pendingActionLabel ? (
            <div className="auth-page__pending">
              <span>登录后继续</span>
              <strong>{pendingActionLabel}</strong>
            </div>
          ) : null}

          <form className="auth-page__form" onSubmit={(event) => void handleSubmit(event)}>
            {mode === "register" ? (
              <label className={`auth-page__field${fieldErrors.betaCode ? " auth-page__field--error" : ""}`}>
                <span>
                  <SafetyOutlined /> 企业邀请码 / 内测码
                </span>
                <input
                  value={betaCode}
                  onChange={(event) => { setBetaCode(event.target.value); clearFieldError("betaCode"); }}
                  onBlur={() => handleFieldBlur("betaCode", betaCode)}
                  placeholder="请输入企业邀请码或内测码"
                  autoComplete="one-time-code"
                />
                {fieldErrors.betaCode ? <span className="auth-page__field-error">{fieldErrors.betaCode}</span> : null}
              </label>
            ) : null}

            {showForgotPassword ? (
              <div className="auth-page__forgot-box">
                <p className="auth-page__forgot-title">重置密码</p>
                {forgotStep === "email" ? (
                  <input value={forgotEmail} onChange={(e) => setForgotEmail(e.target.value)} placeholder="输入注册邮箱" type="email" className="auth-page__forgot-input" />
                ) : forgotStep === "code" ? (
                  <div className="auth-page__sms-row">
                    <input value={forgotCode} onChange={(e) => setForgotCode(e.target.value)} placeholder="输入验证码" maxLength={6} />
                    <button type="button" className="auth-page__sms-btn" disabled={emailCooldown > 0 || isSendingEmail} onClick={() => void handleSendEmailCode("reset")}>
                      {isSendingEmail ? "发送中" : emailCooldown > 0 ? `${emailCooldown}s` : "重新发送"}
                    </button>
                  </div>
                ) : (
                  <input type="password" value={forgotPassword} onChange={(e) => setForgotPassword(e.target.value)} placeholder="输入新密码（至少 6 位）" className="auth-page__forgot-input" />
                )}
                <div className="auth-page__forgot-actions">
                  <button type="button" className="auth-page__forgot-cancel" onClick={() => { setShowForgotPassword(false); setForgotStep("email"); setForgotEmail(""); setForgotCode(""); setForgotPassword(""); setNotice(null); }}>取消</button>
                  <button type="button" className="auth-page__forgot-confirm" onClick={() => void handleForgotPassword()}>
                    {forgotStep === "newPassword" ? "重置密码" : "下一步"}
                  </button>
                </div>
              </div>
            ) : null}

            {!showForgotPassword && authTab === "password" ? (
              <>
                <label className={`auth-page__field${fieldErrors.username ? " auth-page__field--error" : ""}`}>
                  <span>
                    <UserOutlined /> {mode === "register" ? "设置用户名" : "用户名"}
                  </span>
                  <input
                    value={username}
                    onChange={(event) => { setUsername(event.target.value); clearFieldError("username"); }}
                    onBlur={() => handleFieldBlur("username", username)}
                    placeholder="输入用户名或邮箱"
                    autoComplete="username"
                  />
                  {fieldErrors.username ? <span className="auth-page__field-error">{fieldErrors.username}</span> : null}
                </label>
                <label className={`auth-page__field${fieldErrors.password ? " auth-page__field--error" : ""}`}>
                  <span>
                    <LockOutlined /> {mode === "register" ? "设置密码" : "密码"}
                  </span>
                  <input
                    type="password"
                    value={password}
                    onChange={(event) => { setPassword(event.target.value); clearFieldError("password"); }}
                    onBlur={() => handleFieldBlur("password", password)}
                    placeholder={mode === "register" ? "至少 8 位，含字母和数字" : "输入密码"}
                    autoComplete={mode === "login" ? "current-password" : "new-password"}
                  />
                  {fieldErrors.password ? <span className="auth-page__field-error">{fieldErrors.password}</span> : null}
                  {mode === "register" && passwordLooksReady && !fieldErrors.password ? (
                    <span className="auth-page__field-hint">
                      <CheckCircleFilled /> 密码长度符合要求
                    </span>
                  ) : null}
                </label>
                {mode === "login" ? (
                  <div className="auth-page__forgot">
                    <button type="button" onClick={() => { setShowForgotPassword(true); setForgotStep("email"); }}>忘记密码？</button>
                  </div>
                ) : null}
              </>
            ) : null}

            {!showForgotPassword && authTab === "email" ? (
              <>
                {mode === "register" ? (
                  <label className="auth-page__field">
                    <span>
                      <UserOutlined /> 用户名
                    </span>
                    <input
                      value={username}
                      onChange={(event) => setUsername(event.target.value)}
                      placeholder="可选，不填将自动生成"
                      autoComplete="username"
                    />
                  </label>
                ) : null}
                <label className={`auth-page__field${fieldErrors.email ? " auth-page__field--error" : ""}`}>
                  <span>
                    <MailOutlined /> 邮箱
                  </span>
                  <input
                    type="email"
                    value={email}
                    onChange={(event) => { setEmail(event.target.value); clearFieldError("email"); }}
                    onBlur={() => handleFieldBlur("email", email)}
                    placeholder="输入邮箱地址"
                    autoComplete="email"
                  />
                  {fieldErrors.email ? <span className="auth-page__field-error">{fieldErrors.email}</span> : null}
                  {emailLooksValid && !fieldErrors.email ? (
                    <span className="auth-page__field-hint">
                      <CheckCircleFilled /> 邮箱格式正确
                    </span>
                  ) : null}
                </label>
                <label className={`auth-page__field${fieldErrors.password ? " auth-page__field--error" : ""}`}>
                  <span>
                    <LockOutlined /> {mode === "register" ? "设置密码" : "密码"}
                  </span>
                  <input
                    type="password"
                    value={password}
                    onChange={(event) => { setPassword(event.target.value); clearFieldError("password"); }}
                    onBlur={() => handleFieldBlur("password", password)}
                    placeholder={mode === "register" ? "至少 6 位" : "输入密码"}
                    autoComplete={mode === "login" ? "current-password" : "new-password"}
                  />
                  {fieldErrors.password ? <span className="auth-page__field-error">{fieldErrors.password}</span> : null}
                  {mode === "register" && passwordLooksReady && !fieldErrors.password ? (
                    <span className="auth-page__field-hint">
                      <CheckCircleFilled /> 密码长度符合要求
                    </span>
                  ) : null}
                </label>
                {mode === "register" ? (
                  <label className={`auth-page__field${fieldErrors.emailCode ? " auth-page__field--error" : ""}`}>
                    <span>
                      <SafetyOutlined /> 邮箱验证码
                    </span>
                    <div className="auth-page__sms-row">
                      <input
                        value={emailCode}
                        onChange={(event) => { setEmailCode(event.target.value); clearFieldError("emailCode"); }}
                        onBlur={() => handleFieldBlur("emailCode", emailCode)}
                        placeholder="输入 6 位验证码"
                        maxLength={6}
                        autoComplete="one-time-code"
                      />
                      <button
                        type="button"
                        className="auth-page__sms-btn"
                        disabled={emailCooldown > 0 || !email.trim() || isSendingEmail || !betaCode.trim()}
                        onClick={() => void handleSendEmailCode("register")}
                      >
                        {isSendingEmail ? "发送中" : emailCooldown > 0 ? `${emailCooldown}s` : "获取验证码"}
                      </button>
                    </div>
                    {fieldErrors.emailCode ? <span className="auth-page__field-error">{fieldErrors.emailCode}</span> : null}
                  </label>
                ) : null}
              </>
            ) : null}

            {!showForgotPassword && authTab === "phone" ? (
              <>
                <label className={`auth-page__field${fieldErrors.phone ? " auth-page__field--error" : ""}`}>
                  <span>
                    <PhoneOutlined /> 手机号
                  </span>
                  <div className="auth-page__phone-row">
                    <span className="auth-page__phone-prefix">+86</span>
                    <input type="tel" value={phone} onChange={(event) => { setPhone(event.target.value); clearFieldError("phone"); }} onBlur={() => handleFieldBlur("phone", phone)} placeholder="输入手机号" autoComplete="tel" />
                  </div>
                  {fieldErrors.phone ? <span className="auth-page__field-error">{fieldErrors.phone}</span> : null}
                  {phoneLooksValid && !fieldErrors.phone ? (
                    <span className="auth-page__field-hint">
                      <CheckCircleFilled /> 手机号格式正确
                    </span>
                  ) : null}
                </label>
                <label className={`auth-page__field${fieldErrors.smsCode ? " auth-page__field--error" : ""}`}>
                  <span>
                    <SafetyOutlined /> 验证码
                  </span>
                  <div className="auth-page__sms-row">
                    <input value={smsCode} onChange={(event) => { setSmsCode(event.target.value); clearFieldError("smsCode"); }} onBlur={() => handleFieldBlur("smsCode", smsCode)} placeholder="输入 6 位验证码" maxLength={6} />
                    <button
                      type="button"
                      className="auth-page__sms-btn"
                      disabled={smsCooldown > 0 || !phone.trim() || isSendingSms || (mode === "register" && !betaCode.trim())}
                      onClick={() => void handleSendSms()}
                    >
                      {isSendingSms ? "发送中" : smsCooldown > 0 ? `${smsCooldown}s` : "获取验证码"}
                    </button>
                  </div>
                  {fieldErrors.smsCode ? <span className="auth-page__field-error">{fieldErrors.smsCode}</span> : null}
                </label>
                {mode === "register" ? (
                  <label className={`auth-page__field${fieldErrors.password ? " auth-page__field--error" : ""}`}>
                    <span>
                      <LockOutlined /> 设置密码
                    </span>
                    <input type="password" value={password} onChange={(event) => { setPassword(event.target.value); clearFieldError("password"); }} onBlur={() => handleFieldBlur("password", password)} placeholder="至少 6 位" autoComplete="new-password" />
                    {fieldErrors.password ? <span className="auth-page__field-error">{fieldErrors.password}</span> : null}
                    {passwordLooksReady && !fieldErrors.password ? (
                      <span className="auth-page__field-hint">
                        <CheckCircleFilled /> 密码长度符合要求
                      </span>
                    ) : null}
                  </label>
                ) : null}
              </>
            ) : null}

            {!showForgotPassword ? (
              <>
                {notice ? <p className="auth-page__notice">{notice}</p> : null}

                <button type="submit" className="auth-page__submit" disabled={isSubmitting}>
              {isSubmitting ? "处理中..." : mode === "login" ? "登录" : "注册"}
            </button>

            <div className="auth-page__agreement">
              <span>
                {mode === "register" ? "注册即表示同意" : "登录即表示同意"}
                <a href="#">《用户协议》</a>和<a href="#">《隐私政策》</a>
              </span>
            </div>

            <div className="auth-page__divider">
              <span>其他方式</span>
            </div>

            <div className="auth-page__social">
              <button type="button" className="auth-page__social-btn" title="手机号登录" onClick={() => setAuthTab("phone")}>
                <MobileOutlined />
              </button>
            </div>
              </>
            ) : null}
          </form>
        </div>
      </aside>
    </section>
  );
}

export default ProfilePage;
