/* ===================================================================
   vr.jsx — VR / 3D world view

   Embeds the self-contained A-Frame "Embers World" (vrworld/world.html)
   as an isolated iframe so it can be offered as an alternative to the 2D
   battle map. The 3D world is a single global singleton with no teardown
   path, so we mount it once (lazily, the first time VR is opened), keep it
   alive, and just show/hide it. The active 2D map is mirrored into the 3D
   scene via postMessage so picking a map on the table also moves the world.
   =================================================================== */
function VRWorld({ active, currentMap, tod, onExitVr }) {
  const ref = React.useRef(null);
  const readyRef = React.useRef(false);
  const [mounted, setMounted] = React.useState(false);

  // Lazy-mount: only build the heavy A-Frame iframe once VR is first opened.
  React.useEffect(() => { if (active && !mounted) setMounted(true); }, [active, mounted]);

  // Mark the frame ready once it finishes loading so we can sync map + light.
  const onLoad = () => { readyRef.current = true; syncMap(); syncTod(); };

  // Bridge so the rest of the app (e.g. the player hotbar's throwables) can
  // post one-off messages into the 3D world without holding the iframe ref.
  React.useEffect(() => {
    window.__embersPostWorld = (msg) => {
      const iframe = ref.current;
      if (!iframe || !iframe.contentWindow) return;
      try { iframe.contentWindow.postMessage(msg, '*'); } catch (e) {}
    };
    return () => { if (window.__embersPostWorld) delete window.__embersPostWorld; };
  }, []);

  // The 3D HUD owns the menus while in VR. Its "2D" board button asks the
  // parent (us) to drop back to the React 2D tabletop instead of the iframe's
  // own internal 2D map, so 2D ⇄ 3D stays a single, consistent control.
  React.useEffect(() => {
    const onMsg = (e) => {
      const d = e.data;
      if (d && d.type === 'embers:exitTo2D') onExitVr && onExitVr();
    };
    window.addEventListener('message', onMsg);
    return () => window.removeEventListener('message', onMsg);
  }, [onExitVr]);

  const syncMap = () => {
    const iframe = ref.current;
    if (!iframe || !iframe.contentWindow || !currentMap || !currentMap.vr) return;
    try { iframe.contentWindow.postMessage({ type: 'embers:setMap', key: currentMap.id }, '*'); } catch (e) {}
  };

  const syncTod = () => {
    const iframe = ref.current;
    if (!iframe || !iframe.contentWindow || !tod) return;
    try { iframe.contentWindow.postMessage({ type: 'embers:setTOD', key: tod }, '*'); } catch (e) {}
  };

  // Mirror the selected table map into the 3D world (now + a couple of retries
  // to cover the world's async boot, which switches maps ~650ms after load).
  React.useEffect(() => {
    if (!mounted || !active) return;
    syncMap();
    const t1 = setTimeout(syncMap, 800);
    const t2 = setTimeout(syncMap, 1600);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, [mounted, active, currentMap && currentMap.id]);

  // Mirror the chosen time-of-day into the 3D world (same retry window as the map).
  React.useEffect(() => {
    if (!mounted || !active) return;
    syncTod();
    const t1 = setTimeout(syncTod, 800);
    const t2 = setTimeout(syncTod, 1600);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, [mounted, active, tod]);

  const has3d = !!(currentMap && currentMap.vr);

  return (
    <div className={`vr-stage ${active ? 'on' : ''}`} aria-hidden={!active}>
      {mounted ? (
        <iframe
          ref={ref}
          className="vr-frame"
          title="Embers — 3D / VR world"
          src="/vrworld/world.html"
          onLoad={onLoad}
          allow="xr-spatial-tracking; gyroscope; accelerometer; fullscreen"
          allowFullScreen
        />
      ) : (
        <div className="vr-placeholder">Preparing the 3D world…</div>
      )}
      {active && !has3d && (
        <div className="vr-note leather stitched">
          This map has no 3D scene yet — showing the last 3D world.
        </div>
      )}
    </div>
  );
}
window.VRWorld = VRWorld;
