import React, { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import {
  API_BASE,
  buildAuthDenyCallbackUrl,
  getPublicAccountFromPathname,
  getAuthFlowFromSearch,
  LOGO_192_SRC
} from "./config";
import SplashScreen from "./components/SplashScreen";
import RandomSiteBackground from "./components/RandomSiteBackground";
import PublicUserPage from "./components/PublicUserPage";
import PublicUserListPage from "./components/PublicUserListPage";
import UserPortal from "./components/UserPortal";
import AdminPanel from "./components/AdminPanel";

function App() {
  const pathname = window.location.pathname;
  const search = window.location.search;
  const basePrefix = useMemo(() => {
    const baseUrl = import.meta.env.BASE_URL || "/";
    return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
  }, []);
  const authorizePathname = useMemo(() => {
    try {
      return new URL("authorize", `http://x${basePrefix}`).pathname;
    } catch {
      return "/authorize";
    }
  }, [basePrefix]);

  const isAdmin = pathname.startsWith("/admin");
  const isPublicUserList = pathname === "/users";
  const isPublicUser = pathname === "/user" || pathname.startsWith("/user/");
  const isAuthorizeRoute = pathname === authorizePathname;
  const authFlow = useMemo(() => getAuthFlowFromSearch(search), [search]);
  const publicAccount = useMemo(() => getPublicAccountFromPathname(pathname), [pathname]);

  const authDenyHref = useMemo(() => {
    const r = (authFlow?.redirectUri || "").trim();
    if (!r) return "";
    return buildAuthDenyCallbackUrl(r, authFlow?.state || "");
  }, [authFlow]);

  useLayoutEffect(() => {
    const params = new URLSearchParams(search);
    const hasRedirect = (params.get("redirect_uri") || params.get("return_url") || "").trim();
    if (!hasRedirect) return;
    if (isAuthorizeRoute) return;
    if (isAdmin || isPublicUserList || isPublicUser) return;
    const target = new URL("authorize", `${window.location.origin}${basePrefix}`);
    target.search = search;
    window.location.replace(target.href);
  }, [search, pathname, isAuthorizeRoute, isAdmin, isPublicUserList, isPublicUser, basePrefix]);

  const [booting, setBooting] = useState(true);
  const markReady = useMemo(() => () => setBooting(false), []);

  const [imagePreview, setImagePreview] = useState({ open: false, src: "", alt: "" });

  const logoTapCountRef = useRef(0);
  const logoTapResetRef = useRef(null);
  const [adminGateOpen, setAdminGateOpen] = useState(false);
  const [adminGateToken, setAdminGateToken] = useState("");
  const [adminGateError, setAdminGateError] = useState("");
  const [adminGateLoading, setAdminGateLoading] = useState(false);

  const openImagePreview = (src, alt = "") => {
    if (!src) return;
    setImagePreview({ open: true, src, alt });
  };

  const closeImagePreview = () => {
    setImagePreview({ open: false, src: "", alt: "" });
  };

  useEffect(() => {
    const timer = setTimeout(() => setBooting(false), 4000);
    return () => clearTimeout(timer);
  }, []);

  useEffect(() => () => {
    if (logoTapResetRef.current) clearTimeout(logoTapResetRef.current);
  }, []);

  const handleLogoTap = () => {
    if (logoTapResetRef.current) clearTimeout(logoTapResetRef.current);
    logoTapCountRef.current += 1;
    if (logoTapCountRef.current >= 5) {
      logoTapCountRef.current = 0;
      setAdminGateOpen(true);
      setAdminGateError("");
      setAdminGateToken("");
      return;
    }
    logoTapResetRef.current = setTimeout(() => {
      logoTapCountRef.current = 0;
    }, 2600);
  };

  const closeAdminGate = () => {
    setAdminGateOpen(false);
    setAdminGateToken("");
    setAdminGateError("");
    setAdminGateLoading(false);
  };

  const submitAdminGate = async (e) => {
    e.preventDefault();
    const t = adminGateToken.trim();
    if (!t) {
      setAdminGateError("请输入管理员 Token");
      return;
    }
    setAdminGateLoading(true);
    setAdminGateError("");
    try {
      const res = await fetch(`${API_BASE}/api/admin/users`, { headers: { "X-Admin-Token": t } });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        throw new Error(data.error || "Token 无效或无权访问");
      }
      localStorage.setItem("sproutgate_admin_token", t);
      closeAdminGate();
      const base = import.meta.env.BASE_URL || "/";
      const prefix = base.endsWith("/") ? base : `${base}/`;
      window.location.href = new URL("admin", `${window.location.origin}${prefix}`).href;
    } catch (err) {
      setAdminGateError(err.message || "验证失败");
    } finally {
      setAdminGateLoading(false);
    }
  };

  useEffect(() => {
    const isImageUrl = (url) => {
      if (!url) return false;
      const clean = String(url).split("#")[0].split("?")[0];
      return /\.(png|jpe?g|gif|webp|svg)$/i.test(clean);
    };

    const onClick = (event) => {
      const target = event.target;
      if (!(target instanceof HTMLElement)) return;
      if (target.closest && target.closest(".image-preview-card")) return;

      const img = target.tagName === "IMG" ? target : target.closest?.("img");
      if (img && img.closest?.(".markdown-body")) {
        const src = img.getAttribute("src") || "";
        const alt = img.getAttribute("alt") || "";
        if (isImageUrl(src)) {
          event.preventDefault();
          event.stopPropagation();
          openImagePreview(src, alt);
        }
        return;
      }

      const a = target.tagName === "A" ? target : target.closest?.("a[href]");
      if (a && a.closest?.(".markdown-body")) {
        const href = a.getAttribute("href") || "";
        if (isImageUrl(href)) {
          event.preventDefault();
          event.stopPropagation();
          openImagePreview(href, a.getAttribute("title") || a.textContent?.trim() || "");
        }
      }
    };

    document.addEventListener("click", onClick, true);
    return () => document.removeEventListener("click", onClick, true);
  }, []);

  const headerBrand = (
    <div className="app-header-brand">
      <button
        type="button"
        className="app-header-logo-btn"
        onClick={handleLogoTap}
        aria-label="SproutGate 标志"
      >
        <img className="app-header-logo" src={LOGO_192_SRC} alt="" width={40} height={40} decoding="async" />
      </button>
      <div>
        <h1>萌芽账户认证中心</h1>
      </div>
    </div>
  );

  const homeHref = import.meta.env.BASE_URL || "/";
  const usersHref = useMemo(() => {
    try {
      return new URL("users", `${window.location.origin}${basePrefix}`).pathname;
    } catch {
      return "/users";
    }
  }, [basePrefix]);

  const headerNav = (
    <nav>
      <a href={homeHref}>用户中心</a>
      <a href={usersHref}>用户列表</a>
    </nav>
  );

  const headerNavAuthorize = (
    <nav className="oauth-authorize-nav">
      <a href={homeHref}>用户中心</a>
      {authDenyHref ? (
        <a href={authDenyHref} className="oauth-header-deny">拒绝 / 取消</a>
      ) : null}
    </nav>
  );

  return (
    <div className="app-shell">
      <RandomSiteBackground />
      {booting && <SplashScreen />}
      <div className="app">
        {isPublicUserList ? (
          <div className="unified-user-shell">
            <div className="unified-user-card">
              <div className="unified-user-card-accent" aria-hidden />
              <header className="unified-user-header">
                {headerBrand}
                {headerNav}
              </header>
              <div className="unified-user-main">
                <PublicUserListPage onReady={markReady} onPreviewImage={openImagePreview} />
              </div>
            </div>
          </div>
        ) : isPublicUser ? (
          <div className="unified-user-shell">
            <div className="unified-user-card">
              <div className="unified-user-card-accent" aria-hidden />
              <header className="unified-user-header">
                {headerBrand}
                {headerNav}
              </header>
              <div className="unified-user-main">
                <PublicUserPage account={publicAccount} onReady={markReady} onPreviewImage={openImagePreview} />
              </div>
            </div>
          </div>
        ) : isAdmin ? (
          <div className="unified-user-shell">
            <div className="unified-user-card">
              <div className="unified-user-card-accent" aria-hidden />
              <header className="unified-user-header">
                {headerBrand}
                {headerNav}
              </header>
              <div className="unified-user-main">
                <AdminPanel onReady={markReady} />
              </div>
            </div>
          </div>
        ) : isAuthorizeRoute ? (
          <div className="unified-user-shell oauth-authorize-shell">
            <div className="unified-user-card oauth-authorize-card">
              <div className="unified-user-card-accent" aria-hidden />
              <header className="unified-user-header oauth-authorize-header">
                {headerBrand}
                {headerNavAuthorize}
              </header>
              <div className="unified-user-main oauth-authorize-main">
                <UserPortal
                  onReady={markReady}
                  authFlow={authFlow}
                  onPreviewImage={openImagePreview}
                  oauthStandalone
                />
              </div>
            </div>
          </div>
        ) : (
          <div className="unified-user-shell">
            <div className="unified-user-card">
              <div className="unified-user-card-accent" aria-hidden />
              <header className="unified-user-header">
                {headerBrand}
                {headerNav}
              </header>
              <div className="unified-user-main">
                <UserPortal onReady={markReady} authFlow={authFlow} onPreviewImage={openImagePreview} />
              </div>
            </div>
          </div>
        )}
      </div>

      {adminGateOpen && (
        <div className="modal-backdrop" onClick={closeAdminGate}>
          <div className="modal-card" onClick={(e) => e.stopPropagation()}>
            <form onSubmit={submitAdminGate}>
              <div className="modal-header">
                <div>
                  <h2>管理员入口</h2>
                  <p>请输入与后端配置一致的管理员 Token。</p>
                </div>
                <button type="button" className="ghost modal-close" onClick={closeAdminGate}>关闭</button>
              </div>
              <div className="modal-body">
                <label className="full-span">
                  <span className="label-text">管理员 Token</span>
                  <input
                    type="password"
                    autoComplete="off"
                    value={adminGateToken}
                    onChange={(e) => setAdminGateToken(e.target.value)}
                    placeholder="X-Admin-Token"
                  />
                </label>
                {adminGateError && <div className="error full-span">{adminGateError}</div>}
              </div>
              <div className="modal-actions">
                <button type="submit" className="primary" disabled={adminGateLoading}>
                  {adminGateLoading ? "验证中…" : "进入后台"}
                </button>
                <button type="button" className="ghost" onClick={closeAdminGate}>取消</button>
              </div>
            </form>
          </div>
        </div>
      )}

      {imagePreview.open && (
        <div className="modal-backdrop" onClick={closeImagePreview}>
          <div className="modal-card image-preview-card" onClick={(e) => e.stopPropagation()}>
            <div className="image-preview-header">
              <div className="image-preview-meta">
                <div className="image-preview-title">{imagePreview.alt || "图片预览"}</div>
                <div className="image-preview-subtitle">点击遮罩关闭</div>
              </div>
              <button type="button" className="ghost modal-close" onClick={closeImagePreview}>
                关闭
              </button>
            </div>
            <div className="image-preview-body">
              <img className="image-preview-img" src={imagePreview.src} alt={imagePreview.alt || "preview"} />
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

export default App;
