import { lazy, Suspense, useCallback, useEffect, useMemo, useState } from "react";
import {
  BugOutlined,
  CheckCircleFilled,
  CloseOutlined,
  HomeOutlined,
  IdcardOutlined,
  LockOutlined,
  LoadingOutlined,
  LoginOutlined,
  LogoutOutlined,
  MailOutlined,
  MobileOutlined,
  PictureOutlined,
  SafetyOutlined,
  UserOutlined,
  VideoCameraOutlined,
  WalletOutlined,
} from "@ant-design/icons";
import ErrorBoundary from "./components/ErrorBoundary";
import ToastContainer from "./components/toast/ToastContainer";
import { toast } from "./components/toast/toastStore";
import { flushPendingGenerationRecords } from "./api/generationRecordClient";
import { keyServerClient } from "./api/keyServerClient";
import { setUserMaxConcurrency } from "./api/generationConcurrency";
import {
  SERVER_SESSION_EXPIRED_EVENT,
  SERVER_SESSION_REPLACED_EVENT,
  clearAllUserStorage,
  type ServerSessionReplacedDetail,
} from "./api/serverConnection";
import { initNotificationPermission } from "./utils/generationNotifier";
import { reportError } from "./utils/errorReporting";
import { loadDarkGreenTheme } from "./styles/loadDarkGreenTheme";
import { useAppStore, useSessionStore } from "./stores";
import type { WebUserSession } from "./types";
import "./styles/ecommerce-standalone.css";

const EcommercePage = lazy(() => import("./features/ecommerce/EcommercePage"));

type AuthMode = "login" | "register";
type AuthMethod = "account" | "email" | "phone";

interface LocalProfilePageProps {
  session: WebUserSession;
  balance: number;
  imageCount: number;
  videoCount: number;
  onBack: () => void;
  onBugFeedback: () => void;
  onLogout: () => void;
}

function LocalAvatar({ session, size = "md" }: { session: WebUserSession; size?: "sm" | "md" | "lg" }) {
  const displayName = session.user.displayName || session.user.username || "用户";
  const label = displayName.trim().slice(0, 1).toUpperCase() || "用";
  const avatarUrl = session.user.avatarUrl;
  return (
    <span className={`local-user-avatar local-user-avatar--${size}`}>
      {avatarUrl ? <img src={avatarUrl} alt={displayName} /> : <span>{label}</span>}
    </span>
  );
}

function LocalProfilePage({ session, balance, imageCount, videoCount, onBack, onBugFeedback, onLogout }: LocalProfilePageProps) {
  const displayName = session.user.displayName || session.user.username || "用户";
  const workCount = Math.max(imageCount + videoCount, 0);
  const projectCount = 0;
  const assetCount = 0;

  return (
    <section className="local-profile-page">
      <div className="local-profile-page__hero">
        <button type="button" className="local-profile-page__back" onClick={onBack}>
          <HomeOutlined />
          返回工作台
        </button>
      </div>
      <div className="local-profile-page__body">
        <aside className="local-profile-card">
          <div className="local-profile-card__head">
            <span className="local-profile-card__avatar-wrap">
              <LocalAvatar session={session} size="lg" />
              <CheckCircleFilled />
            </span>
            <strong>{displayName}</strong>
            <span className="local-profile-card__uid">UID {session.user.id}</span>
          </div>

          <div className="local-profile-card__stats">
            <span><strong>{projectCount}</strong><em>项目</em></span>
            <span><strong>{workCount}</strong><em>作品</em></span>
            <span><strong>{assetCount}</strong><em>资产</em></span>
          </div>

          <div className="local-profile-card__credits">
            <span><em>可用积分</em><strong>{balance.toFixed(2)}</strong></span>
            <span><em>图片作品</em><strong>{imageCount}</strong></span>
            <span><em>视频作品</em><strong>{videoCount}</strong></span>
          </div>

          <div className="local-profile-card__meta">
            <span><em>当前账号</em><strong>{displayName}</strong></span>
            <span><em>积分余额</em><strong>{balance.toFixed(2)}</strong></span>
          </div>

          <button type="button" className="local-profile-card__primary" onClick={onBack}>
            <HomeOutlined />
            进入工作台
          </button>
          <button type="button" className="local-profile-card__secondary" onClick={onBugFeedback}>
            <BugOutlined />
            Bug 反馈
          </button>
          <button type="button" className="local-profile-card__danger" onClick={onLogout}>
            <LogoutOutlined />
            退出登录
          </button>
        </aside>

        <main className="local-profile-main">
          <div className="local-profile-tabs" role="tablist" aria-label="个人主页分类">
            {["我的作品", "我的项目", "我的资产", "社区发布"].map((item, index) => (
              <button key={item} type="button" className={index === 0 ? "is-active" : ""}>
                {item}
              </button>
            ))}
          </div>

          <section className="local-profile-works">
            <header>
              <div>
                <strong>代表作</strong>
                <span>后续将展示接口返回的真实作品</span>
              </div>
              <em>{workCount} 项</em>
            </header>
            <div className="local-profile-work-grid local-profile-work-grid--empty">
              <div className="local-profile-empty">
                <strong>暂无代表作数据</strong>
                <span>作品接口接入后，这里会显示你的真实生成内容。</span>
              </div>
            </div>
          </section>
        </main>
      </div>
    </section>
  );
}

function App() {
  const session = useSessionStore((s) => s.session);
  const setSession = useSessionStore((s) => s.setSession);
  const clearSessionState = useSessionStore((s) => s.clearSession);
  const usage = useAppStore((s) => s.usage);
  const setUsage = useAppStore((s) => s.setUsage);

  const [authOpen, setAuthOpen] = useState(false);
  const [authMode, setAuthMode] = useState<AuthMode>("login");
  const [authMethod, setAuthMethod] = useState<AuthMethod>("account");
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [betaCode, setBetaCode] = useState("");
  const [authSubmitting, setAuthSubmitting] = useState(false);
  const [authError, setAuthError] = useState<string | null>(null);
  const [sessionNotice, setSessionNotice] = useState<string | null>(null);
  const [profileMenuOpen, setProfileMenuOpen] = useState(false);
  const [currentPage, setCurrentPage] = useState<"workspace" | "profile">("workspace");

  useEffect(() => {
    void loadDarkGreenTheme();
    document.documentElement.dataset.theme = "dark";
    document.documentElement.dataset.uiTheme = "dark-green";
    document.documentElement.style.colorScheme = "dark";
    document.body.classList.add("ecommerce-standalone-body");
    return () => {
      document.body.classList.remove("ecommerce-standalone-body");
    };
  }, []);

  useEffect(() => {
    const splash = document.getElementById("app-boot-splash");
    if (splash) {
      splash.style.opacity = "0";
      const timer = window.setTimeout(() => splash.remove(), 350);
      return () => window.clearTimeout(timer);
    }
  }, []);

  useEffect(() => {
    initNotificationPermission();
  }, []);

  useEffect(() => {
    if (!session) return;
    void flushPendingGenerationRecords();
  }, [session]);

  useEffect(() => {
    const handleUnhandled = (event: ErrorEvent) => {
      reportError(event.error || new Error(event.message), "unhandled");
    };
    const handleRejection = (event: PromiseRejectionEvent) => {
      reportError(event.reason instanceof Error ? event.reason : new Error(String(event.reason)), "rejection");
    };
    window.addEventListener("error", handleUnhandled);
    window.addEventListener("unhandledrejection", handleRejection);
    return () => {
      window.removeEventListener("error", handleUnhandled);
      window.removeEventListener("unhandledrejection", handleRejection);
    };
  }, []);

  const refreshUsage = useCallback(async () => {
    try {
      setUsage(await keyServerClient.getUsageSummary());
    } catch {
      // Usage is helpful but should not block the standalone generator.
    }
  }, [setUsage]);

  const completeAuth = useCallback(
    async (nextSession: WebUserSession) => {
      setSession(nextSession);
      setUserMaxConcurrency(nextSession.user.maxConcurrency);
      setAuthOpen(false);
      setAuthError(null);
      await refreshUsage();
      if (nextSession.user.email && !nextSession.user.emailVerified) {
        toast.info("邮箱尚未验证，部分功能可能受限");
      }
    },
    [refreshUsage, setSession],
  );

  const clearAuthenticatedState = useCallback(() => {
    clearAllUserStorage();
    clearSessionState();
    setUserMaxConcurrency(null);
    setUsage({
      balanceCents: 0,
      imageUsed: 0,
      videoUsed: 0,
      textUsed: 0,
      source: "preview",
    });
  }, [clearSessionState, setUsage]);

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

    const loadSession = async () => {
      try {
        const nextSession = await keyServerClient.getCurrentSession();
        if (cancelled) return;
        setSession(nextSession);
        setUserMaxConcurrency(nextSession?.user.maxConcurrency);
        if (nextSession) await refreshUsage();
      } catch {
        if (!cancelled) clearAuthenticatedState();
      }
    };

    void loadSession();
    return () => {
      cancelled = true;
    };
  }, [clearAuthenticatedState, refreshUsage, setSession]);

  useEffect(() => {
    const handleSessionInvalid = (event: Event) => {
      const detail = (event as CustomEvent<ServerSessionReplacedDetail>).detail;
      clearAuthenticatedState();
      setSessionNotice(detail?.message || "登录状态已失效，请重新登录。");
      setAuthOpen(true);
    };

    window.addEventListener(SERVER_SESSION_REPLACED_EVENT, handleSessionInvalid);
    window.addEventListener(SERVER_SESSION_EXPIRED_EVENT, handleSessionInvalid);
    return () => {
      window.removeEventListener(SERVER_SESSION_REPLACED_EVENT, handleSessionInvalid);
      window.removeEventListener(SERVER_SESSION_EXPIRED_EVENT, handleSessionInvalid);
    };
  }, [clearAuthenticatedState]);

  const openAuth = useCallback((mode: AuthMode = "login") => {
    setAuthMode(mode);
    setAuthError(null);
    setSessionNotice(null);
    setAuthOpen(true);
  }, []);

  const handleSubmitAuth = async () => {
    if (!username.trim() || !password) {
      setAuthError(authMethod === "email" ? "请输入邮箱和密码" : authMethod === "phone" ? "请输入手机号和验证码/密码" : "请输入用户名和密码");
      return;
    }
    setAuthSubmitting(true);
    setAuthError(null);
    try {
      const nextSession =
        authMode === "login"
          ? await keyServerClient.login({ username, password })
          : await keyServerClient.register({ username, password, betaCode });
      await completeAuth(nextSession);
    } catch (error) {
      setAuthError(error instanceof Error ? error.message : "登录失败，请稍后重试。");
    } finally {
      setAuthSubmitting(false);
    }
  };

  const handleLogout = () => {
    setProfileMenuOpen(false);
    setCurrentPage("workspace");
    clearAuthenticatedState();
    toast.info("已退出登录");
  };

  const balance = Math.max(usage.balanceCents, 0) / 100;
  const displayName = session?.user.displayName || session?.user.username || "用户";
  const actualWorkCount = Math.max(usage.imageUsed + usage.videoUsed, 0);
  const shownWorkCount = actualWorkCount;

  const avatarMenuStats = useMemo(
    () => [
      { icon: <IdcardOutlined />, label: "UID", value: session?.user.id ?? "-" },
      { icon: <WalletOutlined />, label: "积分", value: `${balance.toFixed(2)} 积分` },
      { icon: <PictureOutlined />, label: "图片", value: usage.imageUsed },
      { icon: <VideoCameraOutlined />, label: "视频", value: usage.videoUsed },
      { icon: <PictureOutlined />, label: "作品", value: shownWorkCount },
    ],
    [balance, session?.user.id, shownWorkCount, usage.imageUsed, usage.videoUsed],
  );

  const handleOpenProfile = () => {
    setProfileMenuOpen(false);
    setCurrentPage("profile");
  };

  const handleOpenWorkspace = () => {
    setProfileMenuOpen(false);
    setCurrentPage("workspace");
  };

  const handleBugFeedback = () => {
    setProfileMenuOpen(false);
    toast.info("Bug 反馈入口已保留，后续可接入反馈页面。");
  };

  return (
    <div className="ecommerce-standalone web-shell" data-theme="dark" data-ui-theme="dark-green" data-view="ecommerce">
      <header className="ecommerce-standalone__topbar">
        <button type="button" className="ecommerce-standalone__brand" onClick={handleOpenWorkspace}>
          <span className="ecommerce-standalone__logo" aria-hidden="true">
            <img src="https://stringtest.oss-cn-hangzhou.aliyuncs.com/logo.png" alt="" />
          </span>
          <strong>OmniAI 电商智能体</strong>
        </button>
        <div className="ecommerce-standalone__account">
          {session ? (
            <div className="ecommerce-profile-menu">
              <span className="ecommerce-standalone__credits">
                {(Math.max(usage.balanceCents, 0) / 100).toFixed(2)} 积分
              </span>
              <button
                type="button"
                className="ecommerce-profile-menu__trigger"
                onClick={() => setProfileMenuOpen((open) => !open)}
                aria-haspopup="dialog"
                aria-expanded={profileMenuOpen}
              >
                <LocalAvatar session={session} size="sm" />
                <span>{displayName}</span>
              </button>
              {profileMenuOpen ? (
                <>
                  <button
                    type="button"
                    className="ecommerce-profile-popover__backdrop"
                    aria-label="关闭账户信息"
                    onClick={() => setProfileMenuOpen(false)}
                  />
                  <section className="ecommerce-profile-popover" role="dialog" aria-label="账户信息">
                  <div className="ecommerce-profile-popover__head">
                    <LocalAvatar session={session} size="md" />
                    <div>
                      <strong>{displayName}</strong>
                      <span>{session.user.username}</span>
                    </div>
                  </div>

                  <dl className="ecommerce-profile-popover__stats">
                    {avatarMenuStats.map((item) => (
                      <div key={item.label}>
                        <dt>{item.icon}{item.label}</dt>
                        <dd>{item.value}</dd>
                      </div>
                    ))}
                  </dl>

                  <div className="ecommerce-profile-popover__actions">
                    <button type="button" className="is-primary" onClick={handleOpenProfile}>
                      <UserOutlined />
                      个人中心
                    </button>
                    <button type="button" onClick={handleBugFeedback}>
                      <BugOutlined />
                      Bug 反馈
                    </button>
                    <button type="button" className="is-danger" onClick={handleLogout}>
                      <LogoutOutlined />
                      退出
                    </button>
                  </div>
                  </section>
                </>
              ) : null}
            </div>
          ) : (
            <button type="button" onClick={() => openAuth("login")}>
              <LoginOutlined />
              <span>登录 / 注册</span>
            </button>
          )}
        </div>
      </header>

      <main className="ecommerce-standalone__content">
        {session ? (
          <div className="ecommerce-standalone__page" hidden={currentPage !== "profile"}>
            <LocalProfilePage
              session={session}
              balance={balance}
              imageCount={usage.imageUsed}
              videoCount={usage.videoUsed}
              onBack={handleOpenWorkspace}
              onBugFeedback={handleBugFeedback}
              onLogout={handleLogout}
            />
          </div>
        ) : null}
        {/* 工作台常驻挂载，仅用 hidden 切换。切到个人中心时不卸载，
            生成任务、进度动画、已上传图片等本地状态全部保留，切回即继续。 */}
        <div className="ecommerce-standalone__page" hidden={Boolean(session) && currentPage === "profile"}>
          <ErrorBoundary>
            <Suspense
              fallback={
                <div className="page-loading-center">
                  <div className="page-loading-spinner" />
                  <span className="page-loading-center__text">加载中...</span>
                </div>
              }
            >
              <EcommercePage
                projects={[]}
                isAuthenticated={Boolean(session)}
                onStartCreate={() => undefined}
                onOpenProject={() => undefined}
                onDeleteProject={() => undefined}
                onImportWorkflow={() => undefined}
                onCreateTask={() => undefined}
                onRequireLogin={() => openAuth("login")}
                initialTemplate={null}
                onInitialTemplateConsumed={() => undefined}
              />
            </Suspense>
          </ErrorBoundary>
        </div>
      </main>

      {authOpen ? (
        <div className="ecommerce-auth-modal" role="dialog" aria-modal="true" aria-labelledby="ecommerce-auth-title">
          <button
            type="button"
            className="ecommerce-auth-modal__scrim"
            aria-label="关闭登录弹窗"
            onClick={() => setAuthOpen(false)}
          />
          <section className="ecommerce-auth-modal__panel">
            <button
              type="button"
              className="ecommerce-auth-modal__close"
              aria-label="关闭"
              onClick={() => setAuthOpen(false)}
            >
              <CloseOutlined />
            </button>
            <span className="ecommerce-auth-modal__logo" aria-hidden="true">
              <img src="https://stringtest.oss-cn-hangzhou.aliyuncs.com/logo.png" alt="" />
            </span>
            <h2 id="ecommerce-auth-title">{authMode === "login" ? "欢迎回来" : "创建账号"}</h2>
            <p className="ecommerce-auth-modal__subtitle">{authMode === "login" ? "登录后继续你的 AI 创作之旅" : "注册即可免费体验全部功能"}</p>
            {sessionNotice ? <p className="ecommerce-auth-modal__notice">{sessionNotice}</p> : null}

            <div className="ecommerce-auth-modal__tabs" role="tablist" aria-label="账号操作">
              <button type="button" className={authMode === "login" ? "is-active" : ""} onClick={() => { setAuthMode("login"); setAuthError(null); }}>登录</button>
              <button type="button" className={authMode === "register" ? "is-active" : ""} onClick={() => { setAuthMode("register"); setAuthError(null); }}>注册</button>
            </div>

            <div className="ecommerce-auth-modal__methods" role="tablist" aria-label="登录方式">
              <button type="button" className={authMethod === "account" ? "is-active" : ""} onClick={() => setAuthMethod("account")}><UserOutlined />账号密码</button>
              <button type="button" className={authMethod === "email" ? "is-active" : ""} onClick={() => setAuthMethod("email")}><MailOutlined />邮箱</button>
              <button type="button" className={authMethod === "phone" ? "is-active" : ""} onClick={() => setAuthMethod("phone")}><MobileOutlined />手机</button>
            </div>

            {authMode === "register" ? (
              <label className="ecommerce-auth-field">
                <span><SafetyOutlined />企业邀请码 / 内测码</span>
                <input value={betaCode} onChange={(event) => setBetaCode(event.target.value)} placeholder="请输入企业邀请码或内测码" />
              </label>
            ) : null}

            {authMethod === "phone" ? (
              <>
                <label className="ecommerce-auth-field">
                  <span><MobileOutlined />手机号</span>
                  <div className="ecommerce-auth-phone-row">
                    <b>+86</b>
                    <input value={username} onChange={(event) => setUsername(event.target.value)} autoComplete="tel" placeholder="输入手机号" />
                  </div>
                </label>
                <label className="ecommerce-auth-field">
                  <span><SafetyOutlined />验证码</span>
                  <div className="ecommerce-auth-code-row">
                    <input value={password} onChange={(event) => setPassword(event.target.value)} inputMode="numeric" placeholder="输入 6 位验证码" />
                    <button type="button" disabled>获取验证码</button>
                  </div>
                </label>
              </>
            ) : (
              <>
                <label className="ecommerce-auth-field">
                  <span>{authMethod === "email" ? <MailOutlined /> : <UserOutlined />}{authMode === "register" ? authMethod === "email" ? "邮箱" : "设置用户名" : authMethod === "email" ? "邮箱" : "用户名"}</span>
                  <input
                    value={username}
                    onChange={(event) => setUsername(event.target.value)}
                    autoComplete="username"
                    inputMode={authMethod === "email" ? "email" : "text"}
                    placeholder={authMethod === "email" ? "输入邮箱地址" : authMode === "register" ? "输入用户名或邮箱" : "输入用户名或邮箱"}
                  />
                </label>
                <label className="ecommerce-auth-field">
                  <span><LockOutlined />{authMode === "register" ? "设置密码" : "密码"}</span>
                  <input
                    value={password}
                    onChange={(event) => setPassword(event.target.value)}
                    type="password"
                    autoComplete={authMode === "login" ? "current-password" : "new-password"}
                    placeholder={authMode === "register" ? "至少 6 位" : "输入密码"}
                  />
                </label>
              </>
            )}

            {authError ? <p className="ecommerce-auth-modal__error" role="alert">{authError}</p> : null}
            {authMode === "login" && authMethod !== "phone" ? <button type="button" className="ecommerce-auth-modal__forgot">忘记密码?</button> : null}
            <button type="button" className="ecommerce-auth-modal__submit" onClick={handleSubmitAuth} disabled={authSubmitting}>
              {authSubmitting ? <LoadingOutlined /> : null}
              {authMode === "login" ? "登录" : "注册"}
            </button>
            <p className="ecommerce-auth-modal__agreement">{authMode === "login" ? "登录" : "注册"}即表示同意 <a href="#">《用户协议》</a> 和 <a href="#">《隐私政策》</a></p>
            <div className="ecommerce-auth-modal__divider"><span>其他方式</span></div>
            <button type="button" className="ecommerce-auth-modal__mobile-alt" onClick={() => setAuthMethod("phone")} aria-label="手机登录">
              <MobileOutlined />
            </button>
          </section>
        </div>
      ) : null}

      <ToastContainer />
    </div>
  );
}

export default App;
