import { useEffect, useMemo, useRef, useState } from "react";
import type { ReactNode } from "react";
import { publicConfigClient, type WebPublicConfig } from "../api/publicConfigClient";
import { toast } from "./toast/toastStore";
import type { ServerConnectionHealth } from "../api/serverConnection";
import { ossAssets } from "../data/ossAssets";
import { canManageCommunityCases, canReviewCommunity } from "../features/community-review/communityPermissions";
import type { WebNavItem, WebNotification, WebUsageSummary, WebUserSession, WebViewKey } from "../types";
import NotificationCenter from "./NotificationCenter";
import BetaApplicationModal from "./BetaApplicationModal";
import { AnimatedPanel } from "./AnimatedPanel";
import AdminMonitor from "./AdminMonitor";
import { loadRechargeModal, type RechargeModalComponent } from "./RechargeModal/loadRechargeModal";
import { ShellIcon } from "./ShellIcon";
import { loadDarkGreenTheme } from "../styles/loadDarkGreenTheme";

interface AppShellProps {
  activeView: WebViewKey;
  navItems: WebNavItem[];
  session: WebUserSession | null;
  usage: WebUsageSummary;
  notifications: WebNotification[];
  backendHealth: ServerConnectionHealth;
  workspaceExpanded: boolean;
  onSelectView: (view: WebViewKey) => void;
  onLogout: () => void;
  onOpenLogin: () => void;
  onMarkNotificationRead?: (id: string, isRead?: boolean) => void;
  onMarkAllNotificationsRead?: () => void;
  children: ReactNode;
}

const BRAND_LOGO_URL = ossAssets.brand.logo;
const TOOL_SURFACE_VIEW_SET = new Set<WebViewKey>([
  "workbench",
  "canvas",
  "more",
  "scriptTokens",
  "tokenUsage",
  "ecommerceTemplates",
  "sizeTemplate",
  "imageWorkbench",
  "resolutionUpscale",
  "digitalHuman",
  "dialogGenerator",
  "avatarConsole",
  "characterMix",
] as WebViewKey[]);
const PRIMARY_NAV_ORDER: WebViewKey[] = [
  "workbench",
  "ecommerce",
  "sizeTemplate",
  "canvas",
  "scriptTokens",
  "tokenUsage",
  "more",
  "assets",
  "community",
];

function formatBalance(cents: number): string {
  const value = Math.max(0, cents) / 100;
  return `${value.toFixed(2)} 积分`;
}

function canReviewBetaApplications(session: WebUserSession | null): boolean {
  const role = String(session?.user.role || "").trim().toLowerCase();
  const username = String(session?.user.username || "").trim().toLowerCase();
  return role === "admin" || username === "xqy1912";
}

function AppShell({
  activeView,
  navItems,
  session,
  usage,
  notifications,
  workspaceExpanded,
  onSelectView,
  onLogout,
  onOpenLogin,
  onMarkNotificationRead,
  onMarkAllNotificationsRead,
  children,
}: AppShellProps) {
  const profileRef = useRef<HTMLDivElement>(null);
  const submenuHideTimerRef = useRef<number | null>(null);
  const [profileOpen, setProfileOpen] = useState(false);
  const [rechargeOpen, setRechargeOpen] = useState(false);
  const [RechargeModal, setRechargeModal] = useState<RechargeModalComponent | null>(null);
  const [infoOpen, setInfoOpen] = useState(false);
  const [betaOpen, setBetaOpen] = useState(false);
  const infoRef = useRef<HTMLDivElement>(null);
  const [openSubmenuKey, setOpenSubmenuKey] = useState<WebViewKey | null>(null);
  const [publicConfig, setPublicConfig] = useState<WebPublicConfig>({});
  const prevActiveViewRef = useRef<WebViewKey>(activeView);
  const [navJustActivated, setNavJustActivated] = useState<WebViewKey | null>(null);
  const isAuthView = activeView === "login";
  const isImmersiveView = activeView === "agent" || activeView === "avatarConsole";
  const showFloatingNav = !isAuthView && !isImmersiveView && activeView !== "home";
  const showPageScrollActions = showFloatingNav && !TOOL_SURFACE_VIEW_SET.has(activeView);

  const visibleNavItems = useMemo(
    () => {
      const navItemByKey = new Map(navItems.map((item) => [item.key, item]));
      return PRIMARY_NAV_ORDER
        .map((key) => navItemByKey.get(key))
        .filter((item): item is WebNavItem => Boolean(item));
    },
    [navItems],
  );

  useEffect(() => {
    if (activeView !== prevActiveViewRef.current) {
      setNavJustActivated(activeView);
      prevActiveViewRef.current = activeView;
      const timer = window.setTimeout(() => setNavJustActivated(null), 320);
      return () => window.clearTimeout(timer);
    }
  }, [activeView]);

  useEffect(() => {
    if (typeof document === "undefined") {
      return;
    }

    void loadDarkGreenTheme();
    document.documentElement.dataset.theme = "dark";
    document.documentElement.dataset.uiTheme = "dark-green";
    document.documentElement.style.colorScheme = "dark";

    const metaThemeColor = document.querySelector<HTMLMetaElement>("meta[name='theme-color']");
    if (metaThemeColor) {
      metaThemeColor.content = "#0d0d0f";
    }
  }, []);

  useEffect(() => {
    let cancelled = false;
    publicConfigClient
      .get()
      .then((config) => {
        if (!cancelled) setPublicConfig(config);
      })
      .catch(() => {
        if (!cancelled) setPublicConfig({});
      });

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

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

    const handlePointerDown = (event: PointerEvent) => {
      if (!profileRef.current?.contains(event.target as Node)) {
        setProfileOpen(false);
      }
    };

    document.addEventListener("pointerdown", handlePointerDown);
    return () => document.removeEventListener("pointerdown", handlePointerDown);
  }, [profileOpen]);

  useEffect(() => {
    if (!infoOpen) return;
    const handleInfoOutside = (event: PointerEvent) => {
      if (!infoRef.current?.contains(event.target as Node)) {
        setInfoOpen(false);
      }
    };
    document.addEventListener("pointerdown", handleInfoOutside);
    return () => document.removeEventListener("pointerdown", handleInfoOutside);
  }, [infoOpen]);

  useEffect(() => {
    if (!session) {
      setProfileOpen(false);
    }
  }, [session]);

  useEffect(() => {
    return () => {
      if (submenuHideTimerRef.current) {
        window.clearTimeout(submenuHideTimerRef.current);
      }
    };
  }, []);

  useEffect(() => {
    if (!rechargeOpen || RechargeModal) return;

    let cancelled = false;
    void loadRechargeModal().then((component) => {
      if (!cancelled) {
        setRechargeModal(() => component);
      }
    });

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

  const showSubmenu = (key: WebViewKey) => {
    if (submenuHideTimerRef.current) {
      window.clearTimeout(submenuHideTimerRef.current);
      submenuHideTimerRef.current = null;
    }
    setOpenSubmenuKey(key);
  };

  const scheduleHideSubmenu = () => {
    if (submenuHideTimerRef.current) {
      window.clearTimeout(submenuHideTimerRef.current);
    }
    submenuHideTimerRef.current = window.setTimeout(() => {
      setOpenSubmenuKey(null);
      submenuHideTimerRef.current = null;
    }, 1500);
  };

  const scrollActivePage = (direction: "top" | "bottom") => {
    if (typeof document === "undefined") return;

    const targets = [
      ...Array.from(document.querySelectorAll<HTMLElement>(".web-shell__page")),
      ...Array.from(
        document.querySelectorAll<HTMLElement>(
          ".workbench-landing-page, .ecommerce-landing-page, .workspace-page-shell__content, .community-page",
        ),
      ),
      document.scrollingElement as HTMLElement | null,
    ].filter((target): target is HTMLElement => Boolean(target));

    targets.forEach((target) => {
      const top = direction === "top" ? 0 : target.scrollHeight;
      target.scrollTo({ top, behavior: "smooth" });
    });
  };

  const displayName = session?.user.displayName || session?.user.username || "预览创作者";
  const avatarLabel = displayName.trim().slice(0, 1).toUpperCase() || "创";
  const avatarUrl = session?.user.avatarUrl || null;
  const isEnterpriseAccount = Boolean(session?.user.enterpriseId || session?.user.accountType === "enterprise");
  const displayedBalanceCents =
    session && isEnterpriseAccount
      ? (usage.enterpriseBalanceCents ?? session.user.enterpriseBalanceCents ?? usage.balanceCents)
      : usage.balanceCents;
  const displayedBalanceLabel = session ? formatBalance(displayedBalanceCents) : "0 积分";
  const showCommunityReview = canReviewCommunity(session);
  const showCommunityCaseAdd = canManageCommunityCases(session);
  const showBetaApplicationReview = canReviewBetaApplications(session);

  return (
    <div
      className={`web-shell event-strip-hidden${
        isAuthView ? " is-auth-view" : ""
      }${isImmersiveView ? " is-immersive-view" : ""}`}
      data-theme="dark"
      data-ui-theme="dark-green"
      data-view={activeView}
    >
      <div className="web-shell__stage">
        {showFloatingNav ? (
          <aside
            className={`floating-nav${workspaceExpanded ? " is-expanded" : " is-browse"}`}
            aria-label="网页端功能导航"
          >
            {visibleNavItems.map((item, index) => {
              const childActive = item.children?.some((child) => child.key === activeView) ?? false;
              const isActive = activeView === item.key || childActive;

              return (
                <div
                  key={item.key}
                  className={`floating-nav__item${item.children?.length ? " has-children" : ""}${
                    isActive ? " is-active" : ""
                  }${openSubmenuKey === item.key ? " is-submenu-open" : ""}`}
                  onMouseEnter={item.children?.length ? () => showSubmenu(item.key) : undefined}
                  onMouseLeave={item.children?.length ? scheduleHideSubmenu : undefined}
                >
                  <button
                    type="button"
                    className={`floating-nav__button${isActive ? " is-active" : ""}${
                      navJustActivated === item.key ? " nav-just-activated" : ""
                    }${workspaceExpanded && index === 3 ? " has-divider" : ""}`}
                    title={`${item.label} / ${item.hint}`}
                    aria-label={item.label}
                    onClick={() => onSelectView(item.children?.[0]?.key ?? item.key)}
                  >
                    {item.icon}
                    <span className="floating-nav__label">{item.label}</span>
                  </button>
                  {item.children?.length ? (
                    <div className="floating-nav__submenu" aria-label={`${item.label} 子导航`}>
                      {item.children.map((child) => (
                        <button
                          key={child.key}
                          type="button"
                          className={`floating-nav__subbutton${activeView === child.key ? " is-active" : ""}`}
                          title={`${child.label} / ${child.hint}`}
                          aria-label={child.label}
                          onClick={() => onSelectView(child.key)}
                        >
                          {child.icon}
                          <span>{child.label}</span>
                        </button>
                      ))}
                    </div>
                  ) : null}
                </div>
              );
            })}
          </aside>
        ) : null}
        {showPageScrollActions ? (
          <div className="floating-page-scroll-actions" aria-label="页面滚动">
            <button
              type="button"
              className="floating-page-scroll-actions__button"
              title="返回页面顶部"
              aria-label="返回页面顶部"
              onClick={() => scrollActivePage("top")}
            >
              <ShellIcon name="arrow-up" />
            </button>
            <button
              type="button"
              className="floating-page-scroll-actions__button"
              title="到达页面底部"
              aria-label="到达页面底部"
              onClick={() => scrollActivePage("bottom")}
            >
              <ShellIcon name="arrow-down" />
            </button>
          </div>
        ) : null}

        <main className="web-shell__content">
          {!isImmersiveView ? (
            <header className="web-topbar">
            <button className="brand-lockup" type="button" onClick={() => onSelectView("home")}>
              <span className="brand-lockup__mark" aria-hidden="true">
                <img className="brand-lockup__logo" src={BRAND_LOGO_URL} alt="" />
              </span>
              <span className="brand-lockup__name">OmniAI</span>
            </button>
            <div className="web-topbar__actions">
              <button
                type="button"
                className="beta-apply-button"
                title="内测申请"
                aria-label="内测申请"
                onClick={() => setBetaOpen(true)}
              >
                内测申请
              </button>
              {session && (
                <NotificationCenter
                  items={notifications}
                  onNavigate={(view, _targetId) => onSelectView(view)}
                  onMarkRead={onMarkNotificationRead}
                  onMarkAllRead={onMarkAllNotificationsRead}
                />
              )}
              <div className="info-popover-anchor" ref={infoRef}>
                <button
                  className="info-button"
                  type="button"
                  aria-label="网站信息"
                  onClick={() => setInfoOpen((c) => !c)}
                >
                  <ShellIcon name="info-circle" />
                </button>
                <AnimatedPanel open={infoOpen} className="info-popover panel-surface">
                  <dl>
                    <dt>备案信息</dt>
                    <dd>{publicConfig.icpRecord || "由服务器配置"}</dd>
                    <dt>公司地址</dt>
                    <dd>{publicConfig.companyAddress || "由服务器配置"}</dd>
                    <dt>联系电话</dt>
                    <dd>{publicConfig.contactPhone || "由服务器配置"}</dd>
                  </dl>
                  <div className="info-popover__links">
                    <a href="#/bug-feedback" onClick={() => setInfoOpen(false)}>Bug 反馈</a>
                    <a href="#/userAgreement" onClick={() => setInfoOpen(false)}>用户协议</a>
                    <a href="#/privacyPolicy" onClick={() => setInfoOpen(false)}>隐私政策</a>
                  </div>
                </AnimatedPanel>
              </div>
              <button
                className="member-button"
                type="button"
                aria-label={`积分余额 ${displayedBalanceLabel}`}
                onClick={() => toast.info("充值功能即将开放，敬请期待")}
              >
                <ShellIcon name="wallet" />
                <span className="member-button__label">{displayedBalanceLabel}</span>
              </button>
              <div className="profile-popover-anchor" ref={profileRef}>
                <button
                  className={`profile-button${session ? " profile-button--member" : " profile-button--guest"}`}
                  type="button"
                  onClick={() => {
                    if (session) {
                      setProfileOpen((current) => !current);
                    } else {
                      onOpenLogin();
                    }
                  }}
                >
                  {session ? (
                    <>
                      <span className="profile-button__avatar">
                        {avatarUrl ? <img src={avatarUrl} alt={displayName} /> : avatarLabel}
                      </span>
                      <span>{displayName}</span>
                    </>
                  ) : (
                    <>
                      <ShellIcon name="login" />
                      <span>登录 / 注册</span>
                    </>
                  )}
                </button>
                <AnimatedPanel open={session ? profileOpen : false} className="profile-popover panel-surface">
                    <div className="profile-popover__head">
                      <span className="profile-popover__avatar">
                        {avatarUrl ? <img src={avatarUrl} alt={displayName} /> : avatarLabel}
                      </span>
                      <div>
                        <strong>{displayName}</strong>
                        <span>{session ? session.user.role || "已登录" : "预览模式"}</span>
                      </div>
                    </div>
                    <dl className="profile-popover__stats">
                      <dt>UID</dt>
                      <dd>{session?.user.id || "preview"}</dd>
                      <dt>{isEnterpriseAccount ? "企业积分" : "积分"}</dt>
                      <dd>{displayedBalanceLabel}</dd>
                      <dt>图片</dt>
                      <dd>{usage.imageUsed}</dd>
                      <dt>视频</dt>
                      <dd>{usage.videoUsed}</dd>
                    </dl>
                    <div className="profile-popover__footer">
                      <span>{session?.source === "server" ? "服务器会话" : "预览会话"}</span>
                      <button type="button" onClick={onLogout}>
                        <ShellIcon name="logout" />
                        退出
                      </button>
                    </div>
                    <button
                      type="button"
                      className="profile-popover__center-btn"
                      onClick={() => {
                        setProfileOpen(false);
                        onSelectView("login");
                      }}
                    >
                      <ShellIcon name="user" />
                      个人中心
                    </button>
                    <button
                      type="button"
                      className="profile-popover__report-btn"
                      onClick={() => {
                        setProfileOpen(false);
                        onSelectView("report");
                      }}
                    >
                      <ShellIcon name="flag" />
                      Bug 反馈
                    </button>
                    {showCommunityReview ? (
                      <>
                        <button
                          type="button"
                          className="profile-popover__review-btn"
                          onClick={() => {
                            setProfileOpen(false);
                            onSelectView("communityReview");
                          }}
                        >
                          <ShellIcon name="check-circle" />
                          社区审核
                        </button>
                      </>
                    ) : null}
                    {showBetaApplicationReview ? (
                      <button
                        type="button"
                        className="profile-popover__review-btn"
                        onClick={() => {
                          setProfileOpen(false);
                          onSelectView("betaApplications");
                        }}
                      >
                        <ShellIcon name="check-circle" />
                        内测申请审核
                      </button>
                    ) : null}
                    {showCommunityCaseAdd ? (
                      <>
                        <button
                          type="button"
                          className="profile-popover__review-btn"
                          onClick={() => {
                            setProfileOpen(false);
                            onSelectView("communityCaseAdd");
                          }}
                        >
                          <ShellIcon name="plus-circle" />
                          添加案例
                        </button>
                      </>
                    ) : null}
                  </AnimatedPanel>
              </div>
            </div>
            </header>
          ) : null}
          <div className="web-shell__page">{children}</div>
        </main>
      </div>
      {session?.user.role === "admin" ? <AdminMonitor /> : null}
      {rechargeOpen && RechargeModal ? (
        <RechargeModal open={rechargeOpen} onClose={() => setRechargeOpen(false)} currentBalance={displayedBalanceCents} />
      ) : null}
      <BetaApplicationModal open={betaOpen} onClose={() => setBetaOpen(false)} />
    </div>
  );
}

export default AppShell;
