(function() {
  var useState  = React.useState;
  var useEffect = React.useEffect;
  var useRef    = React.useRef;

  /**
   * Interactive multi-GLB scene: exterior shell + stitched interior parts.
   * Walk In fades the shell and lets you orbit / WASD through interior parts.
   * Uses window.mountStitchedScene (ES module) — never dynamic import() from Babel.
   */
  function StitchedModelViewer(props) {
    var shellSrc = props.shellSrc;
    var parts = props.parts || [];
    var alt = props.alt || 'Stitched 3D building';

    var hostRef = useRef(null);
    var cleanupRef = useRef(null);
    var apiRef = useRef(null);

    var _explore = useState(false);
    var explore = _explore[0], setExplore = _explore[1];
    var _busy = useState(true);
    var busy = _busy[0], setBusy = _busy[1];
    var _err = useState(null);
    var err = _err[0], setErr = _err[1];
    var _focus = useState(null);
    var focusId = _focus[0], setFocusId = _focus[1];

    var liveParts = parts.filter(function(p) { return p && p.modelUrl; });
    var partsKey = liveParts.map(function(p) { return p.id + ':' + p.modelUrl; }).join('|');

    // Mount / remount only when models change — not when Walk In toggles
    useEffect(function() {
      if (!shellSrc || !hostRef.current) return;

      var cancelled = false;
      var waitTimer = null;
      setBusy(true);
      setErr(null);

      function disposeActive() {
        if (cleanupRef.current) {
          try { cleanupRef.current(); } catch (e) {}
          cleanupRef.current = null;
        }
        apiRef.current = null;
      }

      function start() {
        if (cancelled || !hostRef.current) return;
        if (!window.mountStitchedScene) {
          setBusy(false);
          setErr('3D engine not loaded yet. Refresh the page and try again.');
          return;
        }
        window.mountStitchedScene(hostRef.current, {
          shellSrc: shellSrc,
          parts: liveParts,
          explore: explore,
          focusPartId: focusId,
        }).then(function(api) {
          if (cancelled) {
            api.dispose();
            return;
          }
          cleanupRef.current = api.dispose;
          apiRef.current = api;
          setBusy(false);
        }).catch(function(e) {
          if (!cancelled) {
            setBusy(false);
            setErr((e && e.message) || 'Could not load stitched 3D scene');
          }
        });
      }

      if (window.mountStitchedScene) {
        start();
      } else {
        var tries = 0;
        waitTimer = setInterval(function() {
          tries += 1;
          if (window.mountStitchedScene || tries > 40) {
            clearInterval(waitTimer);
            waitTimer = null;
            if (!cancelled) start();
          }
        }, 100);
      }

      return function() {
        cancelled = true;
        if (waitTimer) clearInterval(waitTimer);
        disposeActive();
      };
    }, [shellSrc, partsKey]);

    // Apply Walk In / focus without remounting the GLBs
    useEffect(function() {
      if (apiRef.current && typeof apiRef.current.setExplore === 'function') {
        apiRef.current.setExplore(explore, focusId);
      }
    }, [explore, focusId]);

    function toggleWalkIn() {
      setExplore(function(v) {
        var next = !v;
        if (!next) setFocusId(null);
        return next;
      });
    }

    return React.createElement('div', { className: 'stitched-viewer' },
      React.createElement('div', { className: 'stitched-viewer-toolbar' },
        React.createElement('button', {
          type: 'button',
          className: 'btn ' + (explore ? 'btn-v' : 'btn-o'),
          style: { fontSize: 11, padding: '8px 14px' },
          onClick: toggleWalkIn,
          disabled: busy || !!err,
          onMouseEnter: function(){ document.body.classList.add('hov'); },
          onMouseLeave: function(){ document.body.classList.remove('hov'); },
        }, explore ? '⌂ Exit Walk-In' : '🚶 Walk In'),
        explore && React.createElement('span', {
          style: { fontFamily: 'DM Mono, monospace', fontSize: 9, color: 'var(--text-faint)', letterSpacing: '0.06em' },
        }, 'WASD / arrows to move · drag to look'),
        liveParts.length > 0 && React.createElement('div', { className: 'stitched-viewer-parts' },
          liveParts.map(function(p) {
            return React.createElement('button', {
              key: p.id,
              type: 'button',
              className: 'stitched-part-chip' + (focusId === p.id ? ' on' : ''),
              onClick: function() {
                setExplore(true);
                setFocusId(p.id);
              },
              onMouseEnter: function(){ document.body.classList.add('hov'); },
              onMouseLeave: function(){ document.body.classList.remove('hov'); },
            }, p.label || p.role);
          })
        )
      ),
      React.createElement('div', {
        className: 'stitched-viewer-canvas',
        ref: hostRef,
        'aria-label': alt,
      }),
      busy && React.createElement('div', { className: 'stitched-viewer-overlay' }, 'Building interactive scene…'),
      err && React.createElement('div', { className: 'stitched-viewer-overlay err' }, err)
    );
  }

  window.StitchedModelViewer = StitchedModelViewer;
})();
