// ============================================================
// PATCH · hh-board3d.jsx  (Part 4.1 wiring + Part 5)
// Drop-in replacement. Selects the unified city engine (HoleEngineCity,
// forked from rivals-engine.js — see IMPLEMENTATION.md §3) behind a flag,
// and relays the new HUD fields (kills, killStreak, size pill) up to
// Gameplay. Falls back to the shipped HoleEngine when the flag is off,
// so the current build keeps working.
//
//   window.HH_FLAGS = { cityV2: true }   // set in index.html or Settings
// ============================================================
const { useRef: useRefB3, useEffect: useEffectB3 } = React;

function Board3D({ world, level = 1, skin = 'classic', interactive = true, onUpdate, onEmpty, onPickup, preview = false,
  scoreMult = 1, reachBoost = 0, bombSignal = 0, growSignal = 0, titanSignal = 0 }) {
  const canvasRef = useRefB3(null);
  const layerRef = useRefB3(null);
  const engRef = useRefB3(null);
  const cbRef = useRefB3({}); cbRef.current = { onUpdate, onEmpty, onPickup };
  const firstBomb = useRefB3(true);
  const firstGrow = useRefB3(true);
  const firstTitan = useRefB3(true);

  // mount engine once per world/level
  useEffectB3(() => {
    const sk = (window.HH.SKINS.find(s => s.id === skin)) || window.HH.SKINS[0];
    // cityV2 on → the TRUE infinite open world (chunk-streamed); fall back to the
    // finite city engine, then the shipped arena engine, if needed.
    const Engine = (window.HH_FLAGS && window.HH_FLAGS.cityV2)
      ? (window.HoleEngineOpen || window.HoleEngineCity || window.HoleEngine)
      : window.HoleEngine;
    const eng = Engine(canvasRef.current, layerRef.current, {
      world, level, interactive: preview ? false : interactive,
      skinGlow: sk.glow === 'conic' ? '#ffffff' : sk.glow,
      skinTex: sk.img || null,
      skinId: sk.id,            // drives the premium in-game VFX family (hole-vfx.js)
      skinVfx: sk.vfx || null,  // optional explicit family override
      skinRim: sk.rim || null,
      onUpdate: (s) => cbRef.current.onUpdate && cbRef.current.onUpdate(s),
      onEmpty: (s) => cbRef.current.onEmpty && cbRef.current.onEmpty(s),
      onPickup: (id) => cbRef.current.onPickup && cbRef.current.onPickup(id),
    });
    engRef.current = eng;
    window.__HHENG = eng;
    return () => { eng.destroy(); if (window.__HHENG === eng) window.__HHENG = null; };
  }, [world.id, level]);

  // live prop syncing (preview boards auto-play and never pause)
  useEffectB3(() => { if (!preview) engRef.current && engRef.current.setPaused(!interactive); }, [interactive]);
  useEffectB3(() => { engRef.current && engRef.current.setScoreMult && engRef.current.setScoreMult(scoreMult); }, [scoreMult]);
  useEffectB3(() => { engRef.current && engRef.current.setReachBoost && engRef.current.setReachBoost(reachBoost); }, [reachBoost]);
  useEffectB3(() => { if (firstBomb.current) { firstBomb.current = false; return; } engRef.current && engRef.current.bomb && engRef.current.bomb(); }, [bombSignal]);
  useEffectB3(() => { if (firstGrow.current) { firstGrow.current = false; return; } engRef.current && engRef.current.grow && engRef.current.grow(); }, [growSignal]);
  useEffectB3(() => { if (firstTitan.current) { firstTitan.current = false; return; } engRef.current && engRef.current.titan && engRef.current.titan(7000); }, [titanSignal]);

  return (
    <div style={{ position: 'absolute', inset: 0, overflow: 'hidden' }}>
      <canvas ref={canvasRef} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', touchAction: 'none', display: 'block' }}></canvas>
      <div ref={layerRef} style={{ position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none', zIndex: 40 }}></div>
    </div>
  );
}

Object.assign(window, { Board3D });
