import { useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { Link, NavLink, Outlet, useLocation } from "react-router-dom";
import GuideMascot from "./GuideMascot";
import AIDebugObservatory from "./AIDebugObservatory";
import { usePlayerProgress } from "../hooks/usePlayerProgress";
import { api } from "../lib/api";
import { AppIcon, RouteIcon, type IconName } from "./PixelIcons";

function fmtAssets(v: number | null | undefined) {
  if (v == null || Number.isNaN(v)) return "—";
  const sign = v < 0 ? "-" : "";
  return `${sign}$${Math.abs(v).toLocaleString(undefined, { maximumFractionDigits: 0 })}`;
}

const NAV: { section: string; items: { to: string; icon: IconName; label: string }[] }[] = [
  {
    section: "觀測",
    items: [
      { to: "/", icon: "castle", label: "今日 · 基地" },
      { to: "/market", icon: "world", label: "市場 · 世界" },
    ],
  },
  {
    section: "研究",
    items: [{ to: "/research", icon: "folder", label: "個股 · 背包" }],
  },
  {
    section: "修練",
    items: [
      { to: "/skills", icon: "scroll", label: "心法 · 技能樹" },
      { to: "/patterns", icon: "cards", label: "線型 · 圖鑑" },
    ],
  },
  {
    section: "我的",
    items: [
      { to: "/journal", icon: "folder", label: "復盤 · 戰績" },
      { to: "/profile", icon: "wizard", label: "角色 · 養成" },
      { to: "/settings", icon: "gear", label: "設定" },
    ],
  },
];

const BOTTOM_NAV: { to: string; icon: IconName; label: string }[] = [
  { to: "/", icon: "castle", label: "基地" },
  { to: "/market", icon: "world", label: "市場" },
  { to: "/research", icon: "folder", label: "背包" },
  { to: "/skills", icon: "scroll", label: "心法" },
];

function NavLinks({ onNavigate }: { onNavigate?: () => void }) {
  return (
    <nav className="nav">
      {NAV.map((g) => (
        <div key={g.section}>
          <div className="nav-section">{g.section}</div>
          {g.items.map((it) => (
            <NavLink key={it.to} to={it.to} end={it.to === "/"} onClick={onNavigate}>
              <span className="ico">
                <RouteIcon to={it.to} size={22} />
              </span>
              {it.label}
            </NavLink>
          ))}
        </div>
      ))}
    </nav>
  );
}

function useMobileNav() {
  const [isMobile, setIsMobile] = useState(() =>
    typeof window !== "undefined" ? window.matchMedia("(max-width: 920px)").matches : false
  );
  useEffect(() => {
    const mq = window.matchMedia("(max-width: 920px)");
    const sync = () => setIsMobile(mq.matches);
    sync();
    mq.addEventListener("change", sync);
    return () => mq.removeEventListener("change", sync);
  }, []);
  return isMobile;
}

export default function Chrome() {
  const [navOpen, setNavOpen] = useState(false);
  const isMobile = useMobileNav();
  const location = useLocation();
  const { player } = usePlayerProgress();
  const portfolioQ = useQuery({
    queryKey: ["portfolio-total"],
    queryFn: api.portfolioTotal,
    staleTime: 45_000,
    refetchOnWindowFocus: true,
  });
  const xpPct = player?.xpToNext ? Math.round((player.xpInLevel / player.xpToNext) * 100) : 0;
  const portfolio = portfolioQ.data;

  useEffect(() => {
    setNavOpen(false);
  }, [location.pathname]);

  useEffect(() => {
    document.body.classList.toggle("nav-open", navOpen);
    return () => document.body.classList.remove("nav-open");
  }, [navOpen]);

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setNavOpen(false);
    };
    const onResize = () => {
      if (!window.matchMedia("(max-width: 920px)").matches) setNavOpen(false);
    };
    window.addEventListener("keydown", onKey);
    window.addEventListener("resize", onResize);
    return () => {
      window.removeEventListener("keydown", onKey);
      window.removeEventListener("resize", onResize);
    };
  }, []);

  return (
    <div className="layout">
      <button
        type="button"
        className={"nav-backdrop" + (navOpen ? " open" : "")}
        aria-label="關閉選單"
        onClick={() => setNavOpen(false)}
      />

      <aside className={"sidebar" + (navOpen ? " open" : "")} aria-hidden={isMobile && !navOpen}>
        <div className="brand">
          <span className="logo">
            <AppIcon name="compass" size={28} framed glow variant="hero" />
          </span>
          <div>
            <div className="title">投資冒險者</div>
            <div className="sub">OBSERVATORY</div>
          </div>
          <button type="button" className="nav-close" aria-label="關閉選單" onClick={() => setNavOpen(false)}>
            ✕
          </button>
        </div>
        <NavLinks onNavigate={() => setNavOpen(false)} />
        <div className="sidebar-foot">
          資料僅供學習
          <br />
          不構成投資建議
        </div>
      </aside>

      <div className="main">
        <header className="topbar">
          <button
            type="button"
            className="nav-toggle"
            aria-label="開啟選單"
            aria-expanded={navOpen}
            onClick={() => setNavOpen((v) => !v)}
          >
            <span />
            <span />
            <span />
          </button>
          <div className="hero-chip">
            <div className="avatar">
              <AppIcon name="wizard" size={32} framed variant="nav" />
            </div>
            <div className="hero-meta">
              <div className="name">{player?.displayName || "投資冒險者"}</div>
              <div className="lvl">
                {player ? (
                  <>
                    <span>Lv.{player.level} · {player.title}</span>
                    {player.epithet ? <span className="hero-epithet">「{player.epithet}」</span> : null}
                  </>
                ) : (
                  "載入中…"
                )}
              </div>
            </div>
          </div>
          <div className="xp-wrap">
            <div className="xp-label">
              <span>EXP</span>
              <span>
                {player
                  ? `${player.xpInLevel.toLocaleString()} / ${player.xpToNext.toLocaleString()}`
                  : "—"}
              </span>
            </div>
            <div className="bar">
              <span style={{ width: `${xpPct}%` }} />
            </div>
          </div>
          <div className="topbar-right">
            <Link
              to="/journal"
              className="coin topbar-assets"
              title={
                portfolio
                  ? `現金 ${fmtAssets(portfolio.totalCash)} ＋ 持倉 ${fmtAssets(portfolio.totalStock)}${
                      portfolio.accountNames?.length
                        ? `（${portfolio.accountNames.join("、")}）`
                        : ""
                    }`
                  : "前往查看帳戶資產"
              }
            >
              <AppIcon name="coin" size={18} framed variant="nav" />
              <span className="topbar-assets-col">
                <span className="topbar-assets-label">總資產</span>
                <span className="topbar-assets-val">
                  {portfolioQ.isLoading ? "…" : fmtAssets(portfolio?.totalAssets)}
                </span>
              </span>
            </Link>
          </div>
        </header>

        <nav className="bottom-nav" aria-label="主要導覽">
          {BOTTOM_NAV.map((it) => (
            <NavLink key={it.to} to={it.to} end={it.to === "/"}>
              <span className="ic">
                <AppIcon name={it.icon} size={22} framed variant="nav" />
              </span>
              <span className="lb">{it.label}</span>
            </NavLink>
          ))}
          <button type="button" className="bottom-nav-more" onClick={() => setNavOpen(true)}>
            <span className="ic">
              <AppIcon name="menu" size={20} framed={false} />
            </span>
            <span className="lb">更多</span>
          </button>
        </nav>

        <main className="content">
          <Outlet />
        </main>
        <GuideMascot />
        <AIDebugObservatory />
      </div>
    </div>
  );
}
