/* ============================================================
   F2 UI — bootstrap
   Sets up the shared global namespace every other script reads:
     window.F2        — all components (DS bundle + new) + Icon helper
     window.F2Stories — the story registry (story files push here)
     window.story()   — convenience registrar
   This script MUST run after the DS bundle + React + Lucide.
   ============================================================ */
(function () {
  const DS = window.F2TechnologiesDesignSystem_8eccba || {};

  /* ---- Lucide line-icon helper (1.6px stroke per F2 spec) ---- */
  function lucideSvg(name, { size = 18, stroke = 1.6, color = 'currentColor' } = {}) {
    const lib = window.lucide && window.lucide.icons ? window.lucide.icons : null;
    const node = lib ? (lib[name] || lib[toPascal(name)]) : null;
    if (!node) return '';
    const children = node
      .map(([tag, attrs]) => {
        const a = Object.entries(attrs || {})
          .map(([k, v]) => `${k}="${v}"`)
          .join(' ');
        return `<${tag} ${a}></${tag}>`;
      })
      .join('');
    return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="${stroke}" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${children}</svg>`;
  }
  function toPascal(s) {
    return String(s).replace(/(^|[-_\s])(\w)/g, (_, __, c) => c.toUpperCase());
  }

  function Icon({ name, size = 18, stroke = 1.6, color = 'currentColor', style = {}, title }) {
    return React.createElement('span', {
      role: title ? 'img' : undefined,
      'aria-label': title || undefined,
      style: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 auto', ...style },
      dangerouslySetInnerHTML: { __html: lucideSvg(name, { size, stroke, color }) },
    });
  }

  /* ---- Shared namespace ---- */
  window.F2 = Object.assign({}, DS, { Icon, lucideSvg });

  /* ---- Story registry ---- */
  window.F2Stories = [];
  window.story = function (s) {
    if (!s || !s.id) { console.warn('story() needs an id', s); return; }
    if (window.F2Stories.some((x) => x.id === s.id)) {
      console.warn('duplicate story id:', s.id);
      return;
    }
    window.F2Stories.push(s);
  };

  /* ---- Small shared hooks/utils used across the shell ---- */
  window.SB = window.SB || {};
  window.SB.useStored = function (key, initial) {
    const [v, setV] = React.useState(() => {
      try {
        const raw = localStorage.getItem(key);
        return raw === null ? initial : JSON.parse(raw);
      } catch (e) { return initial; }
    });
    React.useEffect(() => {
      try { localStorage.setItem(key, JSON.stringify(v)); } catch (e) {}
    }, [key, v]);
    return [v, setV];
  };

  // inject a <style> once (keeps complex components self-contained)
  window.SB.injectCss = function (id, css) {
    if (document.getElementById(id)) return;
    const s = document.createElement('style');
    s.id = id; s.textContent = css; document.head.appendChild(s);
  };

  // close-on-outside-click / Escape for popovers, menus, dialogs
  window.SB.useDismiss = function (ref, onClose, active) {
    React.useEffect(() => {
      if (active === false) return undefined;
      function onDown(e) { if (ref.current && !ref.current.contains(e.target)) onClose(); }
      function onKey(e) { if (e.key === 'Escape') onClose(); }
      document.addEventListener('mousedown', onDown);
      document.addEventListener('keydown', onKey);
      return () => { document.removeEventListener('mousedown', onDown); document.removeEventListener('keydown', onKey); };
    }, [ref, onClose, active]);
  };

  console.log('[F2 UI] bootstrap ready — components:', Object.keys(window.F2).length);
})();
