// ==========================================================================
// App — Top navbar + breadcrumb row + sidebar + main
// ==========================================================================

const NAV = window.DS_NAV || [
  {
    num: "0", id: "userflow", en: "Userflow", zh: "操作流程圖",
    items: [
      { id: "u-diagrams", en: "Userflow Diagrams", zh: "操作流程圖" },
    ],
  },
  {
    num: "1", id: "foundations", en: "Primitive", zh: "基礎層",
    items: [
      { id: "f-brand",      en: "Brand & Logo",   zh: "品牌辨識系統" },
      { id: "s-palette",    en: "Palette",        zh: "色票" },
      { id: "f-type",       en: "Typography",     zh: "字型" },
      { id: "f-spacing",    en: "Spacing",        zh: "間距" },
      { id: "f-radius",     en: "Radius / Shape", zh: "圓角" },
      { id: "f-shadow",     en: "Shadow",         zh: "陰影" },
      { id: "f-border",     en: "Border width",   zh: "邊框" },
      { id: "f-breakpoint", en: "Breakpoint",     zh: "斷點" },
      { id: "f-transition", en: "Transitions",    zh: "動效" },
      { id: "f-zindex",     en: "zIndex",         zh: "層級" },
    ],
  },
  {
    num: "2", id: "principles", en: "Principles", zh: "規範",
    items: [
      { id: "p-color",   en: "Color",         zh: "色彩系統" },
      { id: "p-buttons", en: "Buttons",       zh: "按鈕" },
      { id: "p-a11y",    en: "Accessibility", zh: "無障礙" },
      { id: "p-voice",   en: "Voice & Tone",  zh: "語氣文案" },
    ],
  },
  {
    num: "3", id: "components", en: "Components", zh: "元件庫",
    items: [
      { id: "c-inputs", en: "Inputs", zh: "資料輸入", children: [
        { id: "c-inputs-autocomplete", en: "Autocomplete",            zh: "下拉搜尋框" },
        { id: "c-inputs-button",       en: "Button",                  zh: "按鈕" },
        { id: "c-inputs-button-group", en: "Button Group",            zh: "按鈕組合" },
        { id: "c-inputs-checkbox",     en: "Checkbox",                zh: "核取按鈕" },
        { id: "c-inputs-fab",          en: "Floating Action Button",  zh: "浮動操作按鈕" },
        { id: "c-inputs-number",       en: "Number Field",            zh: "數字輸入框" },
        { id: "c-inputs-radio",        en: "Radio Group",             zh: "單選框" },
        { id: "c-inputs-select",       en: "Select",                  zh: "下拉選擇框" },
        { id: "c-inputs-rating",       en: "Rating",                  zh: "評分" },
        { id: "c-inputs-slider",       en: "Slider",                  zh: "滑桿" },
        { id: "c-inputs-switch",       en: "Switch",                  zh: "開關按鈕" },
        { id: "c-inputs-textfield",    en: "Text Field",              zh: "文字輸入框" },
        { id: "c-inputs-transfer",     en: "Transfer List",           zh: "雙列轉移選擇框" },
        { id: "c-inputs-toggle",       en: "Toggle Button",           zh: "切換按鈕" },
        { id: "c-inputs-upload",       en: "Upload",                  zh: "上傳" },
        { id: "c-inputs-cascader",     en: "Cascader",                zh: "級聯選擇器" },
        { id: "c-inputs-colorpicker",  en: "ColorPicker",             zh: "顏色選擇器" },
        { id: "c-inputs-datepicker",   en: "DatePicker / TimePicker", zh: "日期 / 時間選擇器" },
        { id: "c-inputs-camera",       en: "Camera",                  zh: "相機" },
      ]},
      { id: "c-display", en: "Data Display", zh: "數據顯示", children: [
        { id: "c-display-avatar",     en: "Avatar",            zh: "頭像" },
        { id: "c-display-badge",      en: "Badge",             zh: "標記 / 徽章" },
        { id: "c-display-chip",       en: "Chip",              zh: "片狀標籤" },
        { id: "c-display-tag",        en: "Tag",               zh: "標籤" },
        { id: "c-display-divider",    en: "Divider",           zh: "分割線" },
        { id: "c-display-icons",      en: "Icons",             zh: "圖示" },
        { id: "c-display-list",       en: "Lists",             zh: "清單 / 列表" },
        { id: "c-display-table",      en: "Table",             zh: "數據表格" },
        { id: "c-display-tooltip",    en: "Tooltip",           zh: "文字提示" },
        { id: "c-display-popover",    en: "Popover",           zh: "氣泡卡片" },
        { id: "c-display-typography", en: "Typography / Text", zh: "文字排版" },
        { id: "c-display-carousel",   en: "Carousel",          zh: "輪播" },
        { id: "c-display-accordion",  en: "Accordion",         zh: "摺疊面板" },
        { id: "c-display-card",       en: "Card",              zh: "卡片" },
        { id: "c-display-paper",      en: "Paper",             zh: "紙張 / 容器" },
        { id: "c-display-calendar",   en: "Calendar",          zh: "日曆" },
        { id: "c-display-empty",      en: "Empty",             zh: "空狀態" },
        { id: "c-display-qrcode",     en: "QRCode",            zh: "二維碼" },
      ]},
      { id: "c-feedback", en: "Feedback", zh: "回饋", children: [
        { id: "c-feedback-alert",    en: "Alert",         zh: "警告提示" },
        { id: "c-feedback-backdrop", en: "Backdrop",      zh: "背景遮罩" },
        { id: "c-feedback-dialog",   en: "Dialog",        zh: "對話框" },
        { id: "c-feedback-progress", en: "Progress bar",  zh: "進度條" },
        { id: "c-feedback-skeleton", en: "Skeleton",      zh: "骨架屏" },
        { id: "c-feedback-toast",    en: "Toast",         zh: "吐司訊息" },
        { id: "c-feedback-snackbar", en: "Snackbar",      zh: "可互動式提示" },
      ]},
      { id: "c-nav", en: "Navigation", zh: "導航", children: [
        { id: "c-nav-menubar",    en: "Menu Bar & Menu",   zh: "選單列與選單 (PC)" },
        { id: "c-nav-appbar",     en: "App Bar",           zh: "應用程式列" },
        { id: "c-nav-bottom",     en: "Bottom Navigation", zh: "底部導覽 (APP)" },
        { id: "c-nav-breadcrumb", en: "Breadcrumbs",       zh: "麵包屑" },
        { id: "c-nav-drawer",     en: "Drawer",            zh: "側邊抽屜" },
        { id: "c-nav-links",      en: "Links",             zh: "連結" },
        { id: "c-nav-pagination", en: "Pagination",        zh: "頁碼" },
        { id: "c-nav-speeddial",  en: "Speed Dial",        zh: "快速撥號鍵" },
        { id: "c-nav-stepper",    en: "Stepper",           zh: "步驟進度條" },
        { id: "c-nav-tabs",       en: "Tabs",              zh: "標籤頁 / 頁籤" },
        { id: "c-nav-dropdown",   en: "Dropdown",          zh: "動作選單" },
        { id: "c-nav-anchor",     en: "Anchor",            zh: "錨點" },
      ]},
      { id: "c-layout", en: "Layout", zh: "佈局", children: [
        { id: "c-layout-form",      en: "Form",                 zh: "表單" },
        { id: "c-layout-scrollbar", en: "Scrollbar guidelines", zh: "捲軸指南" },
        { id: "c-layout-imagelist", en: "Image List",           zh: "圖片列表" },
        { id: "c-layout-splitter",  en: "Splitter",             zh: "分割器" },
        { id: "c-layout-masonry",   en: "Masonry",              zh: "瀑布流" },
      ]},
    ],
  },
  {
    num: "4", id: "patterns", en: "UI Patterns", zh: "慣用組合",
    items: [
      { id: "u-login",     en: "Login",         zh: "登入" },
      { id: "u-dashboard", en: "Dashboard",     zh: "儀表板" },
      { id: "u-list",      en: "List Page",     zh: "列表頁" },
      { id: "u-form",      en: "Form",          zh: "表單頁" },
      { id: "u-empty",     en: "Empty / Error", zh: "空狀態 / 錯誤" },
      { id: "u-settings",  en: "Settings",      zh: "設定頁" },
      { id: "u-wizard",    en: "Wizard",        zh: "步驟引導" },
      { id: "u-profile",   en: "Profile",       zh: "個人檔案" },
      { id: "u-pricing",   en: "Pricing",       zh: "定價頁" },
    ],
  },
];

const DEFAULT_ROUTE = "f-brand";

// 將 NAV 攤平 — 包含 parent 與 child；每筆紀錄 group 與 parent
const ALL_ITEMS = [];
NAV.forEach(g => {
  g.items.forEach(it => {
    ALL_ITEMS.push({ ...it, group: g, parent: null });
    if (it.children) {
      it.children.forEach(c => {
        ALL_ITEMS.push({ ...c, group: g, parent: it });
      });
    }
  });
});
const ALL_IDS = ALL_ITEMS.map(it => it.id);
const findItem = (id) => ALL_ITEMS.find(it => it.id === id);
window.NAV_MAP = Object.fromEntries(ALL_ITEMS.map(it => [it.id, it]));

// 開機資料（由 ds-gate.js 提供）：hiddenPages 頁面開關、isAdmin、登入信箱
const useBootData = () => {
  const [boot, setBoot] = React.useState(() => window.dsBootData || null);
  React.useEffect(() => {
    if (window.dsBootData) { setBoot(window.dsBootData); return; }
    const on = () => setBoot(window.dsBootData);
    window.addEventListener("ds-boot", on, { once: true });
    return () => window.removeEventListener("ds-boot", on);
  }, []);
  return boot;
};

// 依「隱藏頁面」過濾 NAV：可隱藏整個群組、單一項目、family 子項
const filterNav = (nav, hidden) => {
  if (!hidden || hidden.size === 0) return nav;
  return nav
    .filter(g => !hidden.has(g.id))   // 整個群組被關掉
    .map(g => {
      const items = g.items
        .filter(it => !hidden.has(it.id))
        .map(it => it.children
          ? { ...it, children: it.children.filter(c => !hidden.has(c.id)) }
          : it)
        .filter(it => !it.children || it.children.length > 0);
      return { ...g, items };
    })
    .filter(g => g.items.length > 0);
};

// 頂列：前台專案切換 dropdown（admin 也用）
const ProjectSwitcher = ({ boot }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const close = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);

  const projects = boot?.allProjects || [];
  const currentSlug = boot?.project?.slug;
  if (projects.length <= 1) return null; // 只有一個專案就不顯示

  const goTo = (slug) => {
    if (slug === currentSlug) { setOpen(false); return; }
    location.href = "/?project=" + encodeURIComponent(slug);
  };

  return (
    <div ref={ref} style={{ position: "relative", marginRight: 8 }}>
      <button onClick={() => setOpen(o => !o)}
        style={{
          display: "inline-flex", alignItems: "center", gap: 8,
          padding: "6px 12px", borderRadius: 8,
          border: "1px solid var(--n-200)", background: "#fff",
          cursor: "pointer", fontSize: 13, fontFamily: "inherit",
          color: "var(--n-700)",
        }}>
        <span style={{ fontSize: 10, color: "var(--n-500)", letterSpacing: ".08em", textTransform: "uppercase" }}>切換專案</span>
        <span style={{ width: 1, height: 14, background: "var(--n-300)" }} />
        <span style={{ fontWeight: 600, color: "var(--n-900)" }}>{boot?.project?.name || "—"}</span>
        <svg width="10" height="10" viewBox="0 0 10 10" style={{ transform: open ? "rotate(180deg)" : "none", transition: "transform .15s" }}>
          <path d="M1 3 L5 7 L9 3" fill="none" stroke="currentColor" strokeWidth="1.5" />
        </svg>
      </button>
      {open && (
        <div style={{
          position: "absolute", top: "calc(100% + 6px)", right: 0, zIndex: 50,
          minWidth: 220,
          background: "#fff", border: "1px solid var(--n-200)", borderRadius: 8,
          boxShadow: "0 8px 24px rgba(0,0,0,.08)",
          padding: 6,
        }}>
          {projects.map(p => {
            const active = p.slug === currentSlug;
            return (
              <div key={p.id}
                onClick={() => goTo(p.slug)}
                style={{
                  padding: "10px 12px", borderRadius: 6, cursor: "pointer",
                  background: active ? "var(--blue-50)" : "transparent",
                  fontSize: 13, fontWeight: active ? 600 : 500,
                  color: active ? "var(--blue-600)" : "var(--n-900)",
                }}
                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = "var(--n-50)"; }}
                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = "transparent"; }}>
                {p.name}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
};

// 頂列帳號區：顯示信箱、（admin）後台連結、登出
const AccountMenu = ({ boot }) => {
  if (!boot || !boot.configured) return null;
  const slug = boot.project?.slug || "default";
  const adminHref = "admin.html?project=" + encodeURIComponent(slug);
  const logout = async () => {
    try { await window.dsSupabase?.auth.signOut(); } catch (e) {}
    location.replace("login.html");
  };
  return (
    <div className="ds-account">
      {boot.isAdmin && <a className="ds-account__admin" href={adminHref} target="_blank" rel="noopener">後台管理 ↗</a>}
      <span className="ds-account__email" title={boot.email}>{boot.email}</span>
      <button className="ds-account__logout" onClick={logout}>登出</button>
    </div>
  );
};

const useRoute = () => {
  const read = () => {
    const h = location.hash.slice(1);
    return ALL_IDS.includes(h) ? h : DEFAULT_ROUTE;
  };
  const [route, setRoute] = React.useState(read);
  React.useEffect(() => {
    if (!ALL_IDS.includes(location.hash.slice(1))) {
      history.replaceState(null, "", "#" + DEFAULT_ROUTE);
    }
    const onHash = () => {
      setRoute(read());
      window.scrollTo({ top: 0, behavior: "instant" });
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  return route;
};

// 切換 .is-active class 於目前頁的 Section 與 Card
const useActivePage = (route, codeMode) => {
  React.useEffect(() => {
    if (codeMode) return;
    const item = findItem(route);
    if (!item) return;
    document.querySelectorAll(".ds-section").forEach(s => {
      s.classList.toggle("is-active", s.id === item.group.id);
    });
    document.querySelectorAll(".ds-card").forEach(c => {
      c.classList.toggle("is-active", c.id === route);
    });
  }, [route, codeMode]);
};

const Breadcrumb = ({ route, onToggle, collapsed, codeMode }) => {
  const item = findItem(route);
  if (!item) return null;
  const groupFirstId = item.group.items[0]?.id;
  return (
    <nav className="ds-crumb" aria-label="breadcrumb">
      <button className="ds-topbar__toggle" onClick={onToggle} aria-label="toggle sidebar" style={{ marginRight: 4 }}>
        <Icon name="menu" size={18} />
      </button>
      <a className="ds-crumb__link" href={`#${groupFirstId}`}>
        {item.group.en}
        <span className="ds-crumb__zh">{item.group.zh}</span>
      </a>
      <Icon name="chevR" size={12} color="var(--n-400)" />
      {item.parent && (
        <>
          <a className="ds-crumb__link" href={`#${item.parent.id}`}>
            {item.parent.en}
            <span className="ds-crumb__zh">{item.parent.zh}</span>
          </a>
          <Icon name="chevR" size={12} color="var(--n-400)" />
        </>
      )}
      <span className="ds-crumb__current">
        {item.en}
        <span className="ds-crumb__zh">{item.zh}</span>
      </span>
    </nav>
  );
};

// ==========================================================================
// Sidebar — Foundation/Principles/Patterns 一般 item；Components family 可展開
// ==========================================================================
const SIDEBAR_KEY = "ds-sidebar-state";
const loadSide = () => {
  try { return JSON.parse(localStorage.getItem(SIDEBAR_KEY) || "{}"); }
  catch { return {}; }
};
const saveSide = (s) => { try { localStorage.setItem(SIDEBAR_KEY, JSON.stringify(s)); } catch {} };

const Sidebar = ({ active, nav = NAV, codeMode }) => {
  const initial = loadSide();
  // 群組層級展開狀態
  const [openGroups, setOpenGroups] = React.useState(() => {
    const map = {};
    NAV.forEach(g => { map[g.id] = initial.groups?.[g.id] !== false; });
    return map;
  });
  // c-inputs 等 family 的展開狀態
  const [openFamilies, setOpenFamilies] = React.useState(() => initial.families || {});

  // 確保 active 所屬群組是展開的；如果 active 是 child，其 family 也展開
  React.useEffect(() => {
    const item = findItem(active);
    if (!item) return;
    if (!openGroups[item.group.id]) {
      setOpenGroups(o => ({ ...o, [item.group.id]: true }));
    }
    if (item.parent && !openFamilies[item.parent.id]) {
      setOpenFamilies(o => ({ ...o, [item.parent.id]: true }));
    }
  }, [active]);

  React.useEffect(() => { saveSide({ ...loadSide(), groups: openGroups }); }, [openGroups]);
  React.useEffect(() => { saveSide({ ...loadSide(), families: openFamilies }); }, [openFamilies]);

  const toggleGroup = (id) => setOpenGroups(o => ({ ...o, [id]: !o[id] }));
  const toggleFamily = (id) => setOpenFamilies(o => ({ ...o, [id]: !o[id] }));

  return (
    <aside className="ds-side">
      {/* Code 切換按鈕（移到 sidebar 最上方） */}
      <div className="ds-side__code-row">
        <button
          className={`ds-crumb__code ${codeMode ? "is-on" : ""}`}
          onClick={() => window.dispatchEvent(new Event("ds-code-toggle"))}
          title={codeMode ? "回設計系統視圖" : "查看 Token 程式碼"}
        >
          {`Code </>`}
        </button>
      </div>
      <nav className="ds-nav">
        {nav.map((g) => {
          const isOpen = openGroups[g.id];
          // 計算高度：parent items + (expanded child counts)
          const totalHeight = g.items.reduce((acc, it) => {
            const baseH = 40;
            const childH = it.children && openFamilies[it.id] ? it.children.length * 32 : 0;
            return acc + baseH + childH;
          }, 0);
          return (
            <div key={g.id} className={`ds-nav__group ${isOpen ? "" : "is-collapsed"}`}>
              <div className="ds-nav__label" onClick={() => toggleGroup(g.id)}>
                <span className="ds-nav__label-text">
                  {g.en} {g.zh}
                </span>
                <span className="ds-nav__group-chev"><Icon name="chev" size={12} /></span>
              </div>
              <div className="ds-nav__items" style={{ maxHeight: isOpen ? totalHeight + 8 : 0 }}>
                {g.items.map((it) => it.children
                  ? (
                    <NavFamily key={it.id} item={it} active={active}
                      open={openFamilies[it.id]} onToggle={() => toggleFamily(it.id)} />
                  )
                  : (
                    <a key={it.id} href={`#${it.id}`}
                       className={`ds-nav__item ${active === it.id ? "is-active" : ""}`}>
                      <span className="ds-nav__item-en">{it.en}</span>
                      <span className="ds-nav__item-text ds-nav__item-zh">{it.zh}</span>
                    </a>
                  )
                )}
              </div>
            </div>
          );
        })}
      </nav>
    </aside>
  );
};

const NavFamily = ({ item, active, open, onToggle }) => {
  const isActiveParent = active === item.id || item.children.some(c => c.id === active);
  return (
    <div>
      <div className={`ds-nav__item-parent ${isActiveParent ? "is-active-parent" : ""} ${open ? "is-open" : ""}`}>
        <a href={`#${item.id}`}
           className={`ds-nav__item ${active === item.id ? "is-active" : ""}`}
           style={{ padding: 0 }}>
          <span className="ds-nav__item-en">{item.en}</span>
          <span className="ds-nav__item-text ds-nav__item-zh">{item.zh}</span>
        </a>
        <span className="ds-nav__sub-chev" onClick={(e) => { e.preventDefault(); e.stopPropagation(); onToggle(); }}>
          <Icon name="chevR" size={12} />
        </span>
      </div>
      <div className="ds-nav__subs" style={{ maxHeight: open ? item.children.length * 32 + 4 : 0 }}>
        {item.children.map((c) => (
          <a key={c.id} href={`#${c.id}`}
             className={`ds-nav__sub ${active === c.id ? "is-active" : ""}`}
             title={`${c.en} · ${c.zh}`}>
            <span className="ds-nav__sub-en">{c.en}</span>
            <span className="ds-nav__sub-zh">{c.zh}</span>
          </a>
        ))}
      </div>
    </div>
  );
};

const App = () => {
  const route = useRoute();
  const [codeMode, setCodeMode] = React.useState(false);
  React.useEffect(() => {
    const toggle = () => setCodeMode(c => !c);
    window.addEventListener("ds-code-toggle", toggle);
    return () => window.removeEventListener("ds-code-toggle", toggle);
  }, []);
  useActivePage(route, codeMode);
  const boot = useBootData();
  const nav = React.useMemo(() => filterNav(NAV, boot?.hiddenPages), [boot]);
  const initial = loadSide();
  const [collapsed, setCollapsed] = React.useState(!!initial.collapsed);
  React.useEffect(() => { saveSide({ ...loadSide(), collapsed }); }, [collapsed]);
  const onToggle = () => setCollapsed(c => !c);

  // 用專案名同步 browser tab title
  const projectName = boot?.project?.name;
  React.useEffect(() => {
    if (projectName) document.title = projectName;
  }, [projectName]);

  return (
    <div className={`ds-app ${collapsed ? "is-collapsed" : ""}`}>
      <header className="ds-topbar">
        <div className="ds-topbar__logo">D</div>
        <div className="ds-topbar__brand">
          <div className="ds-topbar__title">{projectName || "設計系統"}</div>
          <div className="ds-topbar__sub">DESIGN SYSTEM</div>
        </div>
        <div className="ds-topbar__spacer" />
        <ProjectSwitcher boot={boot} />
        <AccountMenu boot={boot} />
      </header>
      <Breadcrumb route={route} onToggle={onToggle} collapsed={collapsed} codeMode={codeMode} />
      <div className="ds-app__body">
        <Sidebar active={route} nav={nav} codeMode={codeMode} />
        <main className="ds-main">
          {codeMode ? (
            (() => {
              const TokenCodeView = window.TokenCodeView;
              return TokenCodeView ? <TokenCodeView /> : <div style={{ padding: 40 }}>載入中…</div>;
            })()
          ) : (
            (() => {
              const UserflowSection = window.UserflowSection;
              return (
                <>
                  {UserflowSection ? <UserflowSection /> : null}
                  <Foundations />
                  <Principles />
                  <ComponentsSection />
                  <Patterns />
                </>
              );
            })()
          )}
        </main>
      </div>
    </div>
  );
};

// 等 ds-gate.js 完成登入檢查與開機資料載入後才 render
const __dsMount = () => ReactDOM.createRoot(document.getElementById("root")).render(<App />);
if (window.dsBootReady) __dsMount();
else window.addEventListener("ds-boot", __dsMount, { once: true });
