// Spellstash app shell — shared sidebar + mobile bottom-tab navigation.
//
// Loaded (via <script type="text/babel" src="spellstash-shell.jsx">) BEFORE a
// page's own jsx, the same way spellstash-auth.jsx is. Exposes:
//   window.ssShell.AppShell  — wrap a page's content; renders the left sidebar
//                              on desktop and a bottom tab bar on mobile.
//
// Replaces the old per-page top <Nav>. Calmer, more app-like, and it scales to
// the coming Movers / Watchlist / Alerts pages: add one entry to PRIMARY below.
//
// Keeps the brand: #D05D25 accent (--cm-accent), the dark theme tokens, and the
// existing Logo mark. Account + Raids gating reuse window.ssAuth.

(function () {
  const { useState, useEffect } = React;

  // ── Icons (inline SVG, currentColor, 20px stroke set) ──────────────
  function Icon({ name }) {
    const p = {
      collection: "M4 7h16M4 12h16M4 17h10",                                 // stacked rows
      radar: "M12 12 19 5M12 21a9 9 0 1 1 9-9 M12 16a4 4 0 1 1 4-4",         // signal sweep
      decktech: "M4 6h11v13H4zM8 3h11v3M8 3v3",                              // overlapping cards
      tradable: "M7 7h11l-3-3M17 17H6l3 3",                                  // swap arrows
      lent: "M5 12h12l-4-4M5 12l4 4M19 5v14",                                // hand-off out
      archive: "M3 7h18v4H3zM5 11v9h14v-9M9 15h6",                           // box
      history: "M12 7v5l3 2M21 12a9 9 0 1 1-3-6.7M21 4v4h-4",                // clock + undo
      wishlist: "M6 3h12v18l-6-4-6 4z",                                     // bookmark / saved
      raids: "M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7z",                   // shield
      sentinel: "M2 12s3.6-6.5 10-6.5S22 12 22 12s-3.6 6.5-10 6.5S2 12 2 12Z M12 9.2a2.8 2.8 0 1 0 0 5.6 2.8 2.8 0 0 0 0-5.6Z", // watching eye
      manage: "M12 5v14M5 12h14",                                            // plus / add
      more: "M5 12h.01M12 12h.01M19 12h.01",                                 // dots
      synergy: "M9 15a5 5 0 0 1 0-7l3-3a5 5 0 0 1 7 7l-2 2M15 9a5 5 0 0 1 0 7l-3 3a5 5 0 0 1-7-7l2-2", // chain link
      bracketizer: "M9 4H5v16h4M15 4h4v16h-4M12 9v6",                          // brackets + gauge
      user: "M12 11a3.4 3.4 0 1 0 0-6.8 3.4 3.4 0 0 0 0 6.8M5 20c0-3.6 3.1-6 7-6s7 2.4 7 6",  // person
      out: "M9 5H5v14h4M16 12H9M13 9l3 3-3 3",                               // sign-out
    }[name];
    return (
      <svg className="ss-ico" viewBox="0 0 24 24" width="20" height="20"
        fill="none" stroke="currentColor" strokeWidth="1.6"
        strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d={p} />
      </svg>
    );
  }

  function Logo() {
    return (
      <span className="cm-logo">
        <img className="cm-logo-mark" src="/img/spellstash-favicon-192.png" alt="" />
        <span className="cm-logo-word">Spellstash</span>
      </span>
    );
  }

  // Primary destinations (sidebar top + mobile bottom tabs). Collection-first
  // identity: Collection (what you own + where), Radar (what's new for your
  // commanders), and Cash Out (what it's worth + when to sell). Everything
  // else lives under More.
  const PRIMARY = [
    { key: "collection", label: "Collection", href: "/collection", icon: "collection" },
    { key: "radar", label: "Radar", href: "/radar", icon: "radar", isNew: true },
    { key: "cashout", label: "Cash Out", href: "/cashout", icon: "sentinel" },
  ];
  // More destinations, grouped (sidebar "More" groups / mobile More sheet).
  const TOOLS = [
    { key: "decktech", label: "Deck Tech", href: "/deck-tech", icon: "decktech", beta: true },
    { key: "synergy", label: "Synergy Check", href: "/synergy", icon: "synergy", isNew: true },
    { key: "bracketizer", label: "Bracket Brewer", href: "/bracketizer", icon: "bracketizer", isNew: true },
    { key: "wishlist", label: "Wishlists", href: "/collection?view=wishlist", icon: "wishlist" },
    { key: "tradable", label: "Tradable", href: "/tradable", icon: "tradable" },
  ];
  const HOUSEKEEPING = [
    { key: "lended", label: "Lent out", href: "/lended", icon: "lent" },
    { key: "archive", label: "Sold and traded", href: "/archive", icon: "archive" },
    { key: "history", label: "History", href: "/history", icon: "history" },
    { key: "account", label: "Account", href: "/account", icon: "user" },
  ];

  // Container actions, surfaced from the bottom-nav "Add" popup (not a page
  // button). They route to /collection?manage=X, which the collection page
  // turns into the matching modal. On /collection itself the click dispatches
  // the ss-manage CustomEvent instead so the page opens the modal in place.
  const MANAGE_ACTIONS = [
    { key: "new", label: "New container", glyph: "＋", href: "/collection?manage=new" },
    { key: "import", label: "Import decklist", glyph: "📋", href: "/collection?manage=import" },
    { key: "bulk", label: "Bulk Scan", glyph: "📷", badge: "BETA", href: "/collection?manage=bulk" },
    { key: "pull", label: "Deck List Completer", glyph: "📑", badge: "BETA", href: "/collection?manage=pull" },
    { key: "byset", label: "Add by set", glyph: "🗂", badge: "BETA", isNew: true, href: "/collection?manage=byset" },
  ];

  // Resolve which nav item is current. Explicit `active` prop wins; else infer
  // from the path (so pages do not all have to pass it).
  function resolveActive(active) {
    if (active) return active;
    const path = (window.location.pathname || "").toLowerCase();
    const all = PRIMARY.concat(TOOLS).concat(HOUSEKEEPING).concat([{ key: "raids", href: "/raids" }]);
    const hit = all.find((i) => path === i.href.split("?")[0] || path.indexOf(i.href.split("?")[0] + "/") === 0);
    return hit ? hit.key : "";
  }

  function NavLink({ item, active, onClick }) {
    return (
      <a href={item.href}
        className={"ss-side-link" + (active === item.key ? " is-active" : "")}
        aria-current={active === item.key ? "page" : undefined}
        onClick={onClick}>
        <Icon name={item.icon} />
        <span className="ss-side-label">{item.label}</span>
        {item.beta && <span className="cm-beta-chip ss-side-beta">BETA</span>}
        {item.isNew && <span className="cm-new-chip ss-side-beta">NEW</span>}
      </a>
    );
  }

  function AccountBlock({ email, onSignOut }) {
    const initial = (email || "?").trim().charAt(0).toUpperCase();
    return (
      <div className="ss-acct">
        <a className="ss-acct-avatar" href="/account" aria-label="Account" title="Account" style={{ textDecoration: "none", cursor: "pointer" }}>{initial}</a>
        <a className="ss-acct-email cm-mono" href="/account" title={"Account · " + email} style={{ textDecoration: "none", color: "inherit", cursor: "pointer" }}>{email || "Account"}</a>
        <button className="ss-acct-out" onClick={onSignOut} aria-label="Sign out" title="Sign out">
          <Icon name="out" />
        </button>
      </div>
    );
  }

  function AppShell({ active, session, children }) {
    const [me] = (window.ssAuth && window.ssAuth.useMe) ? window.ssAuth.useMe() : [null];
    const raidsAllowed = !!(me && me.raids_allowed);
    const [sheetOpen, setSheetOpen] = useState(false);
    const [manageOpen, setManageOpen] = useState(false);
    const cur = resolveActive(active);
    const email = (session && session.user && session.user.email) || (me && me.email) || "";
    const signOut = () => {
      setSheetOpen(false);
      if (window.ssAuth && window.ssAuth.signOut) window.ssAuth.signOut("/");
    };
    // Close any open sheet/popup on Escape; lock scroll while one is open.
    useEffect(() => {
      if (!sheetOpen && !manageOpen) return;
      const onKey = (e) => { if (e.key === "Escape") { setSheetOpen(false); setManageOpen(false); } };
      window.addEventListener("keydown", onKey);
      const prior = document.body.style.overflow;
      document.body.style.overflow = "hidden";
      return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = prior; };
    }, [sheetOpen, manageOpen]);

    // On /collection, open the matching modal in place via the ss-manage event
    // instead of navigating; every other page keeps the href fallback.
    const manageClick = (a, close) => (e) => {
      if ((window.location.pathname || "") === "/collection") {
        e.preventDefault();
        window.dispatchEvent(new CustomEvent("ss-manage", { detail: { action: a.key } }));
      }
      close();
    };
    const manageList = (close) => MANAGE_ACTIONS.map((a) => (
      <a key={a.key} href={a.href} className="ss-manage-link" onClick={manageClick(a, close)}>
        <span className="ss-manage-glyph" aria-hidden="true">{a.glyph}</span>
        <span style={{ flex: "1 1 auto" }}>{a.label}</span>
        {a.badge ? <span className="cm-beta-chip">{a.badge}</span> : null}
        {a.isNew ? <span className="cm-new-chip">NEW</span> : null}
      </a>
    ));

    const tools = raidsAllowed
      ? TOOLS.concat([{ key: "raids", label: "Raids", href: "/raids", icon: "raids" }])
      : TOOLS;
    const moreActive = tools.concat(HOUSEKEEPING).some((i) => i.key === cur);

    return (
      <div className="ss-app">
        {/* ── Desktop sidebar ───────────────────────────────── */}
        <aside className="ss-side" aria-label="Primary">
          <a href="/collection" className="ss-side-logo cm-logo--link"><Logo /></a>
          <nav className="ss-side-nav">
            {PRIMARY.map((i) => <NavLink key={i.key} item={i} active={cur} />)}
            <div className="ss-side-manage">
              <button type="button"
                className={"ss-side-link ss-side-managebtn" + (manageOpen ? " is-active" : "")}
                onClick={() => setManageOpen((o) => !o)} aria-expanded={manageOpen} aria-haspopup="menu"
                aria-label="Add">
                <Icon name="manage" /><span className="ss-side-label">Add</span>
              </button>
              {manageOpen && (
                <div className="ss-manage-pop" role="menu">{manageList(() => setManageOpen(false))}</div>
              )}
            </div>
            <div className="ss-side-sect">Tools</div>
            {tools.map((i) => <NavLink key={i.key} item={i} active={cur} />)}
            <div className="ss-side-sect">Housekeeping</div>
            {HOUSEKEEPING.map((i) => <NavLink key={i.key} item={i} active={cur} />)}
          </nav>
          <AccountBlock email={email} onSignOut={signOut} />
        </aside>

        {/* ── Page content (the page supplies its own <main>) ── */}
        <div className="ss-app-main">{children}</div>

        {/* ── Mobile bottom tab bar ─────────────────────────── */}
        <nav className="ss-tabbar" aria-label="Primary">
          {PRIMARY.map((i) => (
            <a key={i.key} href={i.href}
              className={"ss-tab" + (cur === i.key ? " is-active" : "")}
              aria-current={cur === i.key ? "page" : undefined}>
              <Icon name={i.icon} />
              <span className="ss-tab-label">{i.label}</span>
            </a>
          ))}
          <button className={"ss-tab" + (manageOpen ? " is-active" : "")}
            onClick={() => { setSheetOpen(false); setManageOpen((o) => !o); }} aria-expanded={manageOpen} aria-label="Add">
            <Icon name="manage" />
            <span className="ss-tab-label">Add</span>
          </button>
          <button className={"ss-tab" + ((sheetOpen || moreActive) ? " is-active" : "")}
            onClick={() => { setManageOpen(false); setSheetOpen((o) => !o); }} aria-expanded={sheetOpen}
            aria-label="More" aria-current={moreActive ? "page" : undefined}>
            <Icon name="more" />
            <span className="ss-tab-label">More</span>
          </button>
        </nav>

        {/* ── Mobile More sheet ─────────────────────────────── */}
        {sheetOpen && (
          <div className="ss-sheet-scrim" onClick={() => setSheetOpen(false)}>
            <div className="ss-sheet" role="dialog" aria-label="More" onClick={(e) => e.stopPropagation()}>
              <div className="ss-sheet-grip" />
              <div className="ss-sheet-sect">Tools</div>
              {tools.map((i) => (
                <a key={i.key} href={i.href}
                  className={"ss-sheet-link" + (cur === i.key ? " is-active" : "")}
                  aria-current={cur === i.key ? "page" : undefined}
                  onClick={() => setSheetOpen(false)}>
                  <Icon name={i.icon} /><span>{i.label}</span>
                  {i.beta && <span className="cm-beta-chip">BETA</span>}
                  {i.isNew && <span className="cm-new-chip">NEW</span>}
                </a>
              ))}
              <div className="ss-sheet-sect">Housekeeping</div>
              {HOUSEKEEPING.map((i) => (
                <a key={i.key} href={i.href}
                  className={"ss-sheet-link" + (cur === i.key ? " is-active" : "")}
                  aria-current={cur === i.key ? "page" : undefined}
                  onClick={() => setSheetOpen(false)}>
                  <Icon name={i.icon} /><span>{i.label}</span>
                  {i.beta && <span className="cm-beta-chip">BETA</span>}
                  {i.isNew && <span className="cm-new-chip">NEW</span>}
                </a>
              ))}
              <button type="button" className="ss-sheet-link" onClick={signOut}>
                <Icon name="out" /><span>Sign out</span>
              </button>
            </div>
          </div>
        )}

        {/* ── Mobile Add sheet ──────────────────────────────── */}
        {manageOpen && (
          <div className="ss-sheet-scrim ss-manage-sheet-scrim" onClick={() => setManageOpen(false)}>
            <div className="ss-sheet" role="dialog" aria-label="Add" onClick={(e) => e.stopPropagation()}>
              <div className="ss-sheet-grip" />
              {manageList(() => setManageOpen(false))}
            </div>
          </div>
        )}
      </div>
    );
  }

  window.ssShell = { AppShell };
})();
