// store.jsx — GhostLabs "Store · Embedded hardware" section for the studio site
// (the signal.jsx React/Babel SPA). Drop-in, in the same style as the other
// sections. Adapted from the webshop's integration/ghostlabs-site/store.jsx:
// instead of product tiles, it features the two RPG-X1 carrier PCBs as full
// auto-rotating 3D renders (board-viewer.js does the WebGL), and links into the
// shop for the rest. Registers window.SignalStore, exactly like gallery.jsx
// registers its section.
//
// Self-contained: depends only on React (loaded globally) + the sig-* classes /
// --sig-* CSS variables signal.jsx injects. The 3D itself is driven by the
// separate ES module board-viewer.js, which lazy-inits any [data-bv] mount.

(function () {
  const v = (k) => `var(--sig-${k})`;

  // The shop is its own Firebase Hosting site (see the webshop repo). In
  // production the button points at the deployed shop; when this studio site is
  // opened from localhost (Firebase emulator) we point at the local Astro dev
  // server (npm run dev → :4321) so the full flow is testable before deploy.
  const PROD_SHOP_URL = 'https://ghostlabs-shop.web.app';
  const LOCAL_SHOP_URL = 'http://localhost:4321';
  const SHOP_URL =
    typeof location !== 'undefined' && /^(localhost|127\.0\.0\.1)$/.test(location.hostname)
      ? LOCAL_SHOP_URL
      : PROD_SHOP_URL;

  // The two RPG-X1 carrier variants, each shown as its own auto-rotating render.
  // Models are served statically from /models/ by Firebase Hosting. `board` keys
  // the WS2812 layout in board-viewer.js (LED_BOARDS).
  const BOARDS = [
    {
      key: 'full',
      name: 'RPG-X1 · Full',
      size: '50 × 80 mm',
      sku: 'GL-RPG-X1',
      variants: [{ id: 'full', label: 'Full', model3d: '/models/board-x.glb', board: 'x' }],
    },
    {
      key: 'mini',
      name: 'RPG-X1 · Mini',
      size: '50 × 64 mm',
      sku: 'GL-RPG-X1',
      variants: [{ id: 'mini', label: 'Mini', model3d: '/models/board-mini.glb', board: 'mini' }],
    },
  ];

  function useIsMobile() {
    const [m, setM] = React.useState(
      typeof window !== 'undefined' && window.innerWidth <= 760,
    );
    React.useEffect(() => {
      const on = () => setM(window.innerWidth <= 760);
      window.addEventListener('resize', on);
      return () => window.removeEventListener('resize', on);
    }, []);
    return m;
  }

  // One 3D board render + caption. The inner skeleton mirrors the webshop's
  // BoardViewer.astro markup that board-viewer.js expects (data-bv-* hooks).
  function BoardCard({ b }) {
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div className="bvw" data-bv="" data-variants={JSON.stringify(b.variants)} data-sku={b.sku}>
          <div className="bv">
            <div className="bv__mount" data-bv-mount=""></div>
            <div className="bv__overlay" data-bv-overlay="">
              <span className="bv__spinner"></span>
              <span className="sig-mono bv__msg" data-bv-msg="">loading 3D…</span>
              <span className="sig-mono bv__sku">{b.sku}</span>
            </div>
            <div className="bv__hint sig-mono">drag · scroll to zoom</div>
          </div>
          <div className="bv__controls" data-bv-ui="" hidden>
            <div className="bv__group">
              <span className="bv__glabel sig-label">Effect</span>
              <div className="bv__effects" data-bv-effects=""></div>
            </div>
            <div className="bv__group">
              <span className="bv__glabel sig-label">PCB</span>
              <div className="bv__colors" data-bv-colors=""></div>
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 12 }}>
          <div className="sig-h3" style={{ fontSize: 18 }}>{b.name}</div>
          <div className="sig-mono" style={{ fontSize: 12, color: v('text-mute'), letterSpacing: '0.08em' }}>{b.size}</div>
        </div>
      </div>
    );
  }

  function SignalStore() {
    const isMobile = useIsMobile();

    // Kick the (lazy) 3D init once our mounts are in the DOM. board-viewer.js may
    // load before or after React renders this, so call scanAll() now AND when the
    // module announces itself; board-viewer's own MutationObserver is a backstop.
    React.useEffect(() => {
      const go = () => { if (window.GhostBoardViewer) window.GhostBoardViewer.scanAll(); };
      go();
      window.addEventListener('ghostboardviewer:ready', go);
      return () => window.removeEventListener('ghostboardviewer:ready', go);
    }, []);

    return (
      <div
        id="store"
        style={{
          padding: isMobile ? '40px 20px 56px' : '56px 56px 112px',
          borderTop: `1px solid ${v('line')}`,
          maxWidth: 1400, margin: '0 auto',
        }}>
        <div className="sig-eyebrow" style={{ marginBottom: isMobile ? 22 : 28 }}>◇ Store · Embedded hardware</div>
        <h2 className="sig-display" style={{ marginBottom: 14, maxWidth: 820 }}>
          The boards we build for our own work,{' '}
          <span style={{ color: v('accent') }}>made available to yours.</span>
        </h2>
        <p className="sig-body" style={{ maxWidth: 640, marginBottom: isMobile ? 28 : 44 }}>
          Designed, flashed, and assembled in-house — firmware open so the board
          you buy is one you can extend, not a black box. This is the <strong style={{ color: v('text'), fontWeight: 500 }}>RPG-X1</strong>,
          our USB-C SWD carrier for the RP2350B, in both sizes. Spin each board,
          run the light show, and repaint the PCB.
        </p>

        <div
          style={{
            display: 'grid',
            gridTemplateColumns: isMobile ? '1fr' : 'repeat(2, minmax(0, 1fr))',
            gap: isMobile ? 36 : 32,
          }}>
          {BOARDS.map((b) => <BoardCard key={b.key} b={b} />)}
        </div>

        <div style={{ marginTop: isMobile ? 36 : 44 }}>
          <a href={`${SHOP_URL}/products`} className="sig-btn-primary" style={{ textDecoration: 'none' }}>
            Visit the full shop <span style={{ fontSize: 18, lineHeight: 1 }}>→</span>
          </a>
        </div>
      </div>
    );
  }

  window.SignalStore = SignalStore;
})();
