/* Axon.ps website kit — ProductSheet
   A single premium product-detail surface, on-system with the manuscript/orbital
   language. Desktop: a floating "folio" panel with a structural orbital header and
   a crimson signal rule. Mobile: a native-feeling bottom sheet.
   Driven by the decoupled 'axon:product' event (works across all script files).
   Accessible: ESC + backdrop close, focus move-in / restore, focus trap, visible
   focus states, aria-modal, body scroll lock, reduced-motion aware. */
function ProductSheet() {
  const [active, setActive] = React.useState(null); // product id or null
  const originRef = React.useRef(null);
  const panelRef = React.useRef(null);
  const closeRef = React.useRef(null);
  const [closing, setClosing] = React.useState(false);

  const close = React.useCallback(() => {
    setClosing(true);
    setTimeout(() => {
      setClosing(false);
      setActive(null);
      const o = originRef.current;
      if (o && typeof o.focus === 'function') o.focus();
      originRef.current = null;
    }, 240);
  }, []);

  // listen for open requests from any product lens
  React.useEffect(() => {
    const onOpen = (e) => {
      const id = e.detail && e.detail.id;
      if (!id || !PRODUCT_DETAIL[id]) return;
      originRef.current = (e.detail && e.detail.origin) || document.activeElement;
      setClosing(false);
      setActive(id);
    };
    window.addEventListener('axon:product', onOpen);
    return () => window.removeEventListener('axon:product', onOpen);
  }, []);

  // open side-effects: scroll lock, focus move, ESC, focus trap
  React.useEffect(() => {
    if (!active) return;
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const t = setTimeout(() => { if (closeRef.current) closeRef.current.focus(); }, 60);

    const onKey = (e) => {
      if (e.key === 'Escape') { e.preventDefault(); close(); return; }
      if (e.key === 'Tab') {
        const panel = panelRef.current; if (!panel) return;
        const focusable = panel.querySelectorAll('a[href], button:not([disabled]), input, [tabindex]:not([tabindex="-1"])');
        if (!focusable.length) return;
        const first = focusable[0], last = focusable[focusable.length - 1];
        if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
        else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
      }
    };
    document.addEventListener('keydown', onKey);
    return () => { document.body.style.overflow = prevOverflow; clearTimeout(t); document.removeEventListener('keydown', onKey); };
  }, [active, close]);

  if (!active) return null;
  const p = PRODUCT_DETAIL[active];
  const state = closing ? 'closing' : 'open';

  return (
    <div className={'psheet-scrim ' + state} onMouseDown={(e) => { if (e.target === e.currentTarget) close(); }}>
      <div className={'psheet ' + state} role="dialog" aria-modal="true" aria-labelledby="psheet-name" ref={panelRef}>
        {/* structural orbital header — echoes the hero diagram */}
        <div className="psheet-head">
          <svg className="psheet-orbit" viewBox="0 0 160 160" aria-hidden="true">
            <g stroke="var(--ink-1)" fill="none" opacity="0.22" strokeWidth="0.8">
              <polygon points="80,16 138,45 138,115 80,144 22,115 22,45" />
              <circle cx="80" cy="80" r="44" />
            </g>
            <line x1="80" y1="80" x2="138" y2="45" stroke="var(--ink-0)" strokeWidth="1" opacity="0.5" />
            <circle cx="138" cy="45" r="3" fill="var(--signal)" />
          </svg>
          <span className="psheet-lens">
            <ProductLens id={active} size={72} live={!p.soon} dim={false} interactive={false} />
          </span>
          <button className="psheet-close" ref={closeRef} onClick={close} aria-label="Close product details">
            <svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 3 L13 13 M13 3 L3 13" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /></svg>
          </button>
        </div>

        <div className="psheet-body">
          <div className="psheet-meta">
            {p.reveal
              ? <span className="t-caption psheet-cat reveal-redact" aria-hidden="true" style={{ display: 'inline-flex', alignItems: 'center', gap: 6, width: 'min(160px, 58%)', marginTop: 2 }}><span style={{ width: '100%', height: 9, borderRadius: 3, background: 'repeating-linear-gradient(90deg, var(--ink-1) 0 18px, transparent 18px 26px)' }}></span></span>
              : <span className="t-caption psheet-cat">{p.category}</span>}
            {p.reveal
              ? <span className="psheet-status psheet-status-reveal">Awaiting reveal</span>
              : (p.soon && <span className="psheet-status">In development</span>)}
          </div>
          <h3 id="psheet-name" className="psheet-name">{p.name}</h3>

          {p.reveal ? (
            <div className="reveal">
              {/* redacted manuscript lines — details held under seal */}
              <div className="reveal-redact" aria-hidden="true">
                <span style={{ width: '92%' }}></span>
                <span style={{ width: '78%' }}></span>
                <span style={{ width: '85%' }}></span>
              </div>
              {/* wax-seal node with the product initial */}
              <div className="reveal-seal" aria-hidden="true">
                <span className="reveal-seal-ring"></span>
                <span className="reveal-seal-disc">{p.name.charAt(0)}</span>
              </div>
              <p className="reveal-copy">
                This system is sealed for now — <em>kept under wraps until its unveiling.</em>
                <br />Details will be revealed when <strong>{p.name}</strong> is ready.
              </p>
              <div className="psheet-rule" aria-hidden="true"><span className="psheet-rule-pulse"></span></div>
              <div className="psheet-actions">
                <span className="btn btn-sealed" aria-disabled="true">
                  <svg width="13" height="13" viewBox="0 0 16 16" aria-hidden="true" style={{ marginRight: 2 }}>
                    <path d="M4 7V5a4 4 0 0 1 8 0v2M3.4 7h9.2a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H3.4a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1Z" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinejoin="round" />
                  </svg>Reveal pending
                </span>
                <span className="psheet-href">axon.ps{p.href}</span>
              </div>
            </div>
          ) : (
            <>
              <p className="psheet-desc">{p.desc}</p>
              <div className="psheet-rule" aria-hidden="true"><span className="psheet-rule-pulse"></span></div>
              <div className="psheet-actions">
                {p.href && !p.href.startsWith('/products/') ? (
                  <a className="btn btn-ink" href={p.href} onClick={close}><span className="cta-dot" aria-hidden="true"></span>Open product</a>
                ) : (
                  <span className="btn btn-sealed" aria-disabled="true">In development</span>
                )}
                {p.href && !p.href.startsWith('/products/') && <span className="psheet-href">axon.ps{p.href}</span>}
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ProductSheet });
