/* Rolling ZaviFx sphere. three.js when available + motion allowed; static brand fallback otherwise. */
function HeroSphere({ height = 460 }) {
  const mount = React.useRef(null);
  const [failed, setFailed] = React.useState(false);
  const reduce = typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  React.useEffect(() => {
    if (reduce || !window.THREE || !mount.current) { if (!window.THREE) setFailed(true); return; }
    const THREE = window.THREE;
    const el = mount.current;
    const w = el.clientWidth, h = el.clientHeight;
    const mobile = w < 640;
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(38, w / h, 0.1, 100);
    camera.position.set(0, 0.35, 5.2);
    const renderer = new THREE.WebGLRenderer({ antialias: !mobile, alpha: true, powerPreference: 'high-performance' });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, mobile ? 1.5 : 2));
    renderer.setSize(w, h);
    el.appendChild(renderer.domElement);

    const tex = new THREE.TextureLoader().load(window.ASSETS + 'sphere-zavifx-texture.png');
    tex.anisotropy = 4;
    const geo = new THREE.SphereGeometry(1.35, mobile ? 48 : 96, mobile ? 32 : 64);
    const mat = new THREE.MeshStandardMaterial({ map: tex, roughness: 0.24, metalness: 0.12, emissiveMap: tex, emissive: new THREE.Color('#FFFFFF'), emissiveIntensity: 0.22 });
    const ball = new THREE.Mesh(geo, mat);
    scene.add(ball);

    const halo = new THREE.Mesh(
      new THREE.SphereGeometry(1.62, 48, 32),
      new THREE.MeshBasicMaterial({ color: new THREE.Color('#FF7A2F'), transparent: true, opacity: 0.09 })
    );
    scene.add(halo);

    scene.add(new THREE.HemisphereLight(0xffffff, 0x884422, 1.15));
    const key = new THREE.DirectionalLight(0xffffff, 2.6); key.position.set(3, 4, 4); scene.add(key);
    const fill = new THREE.DirectionalLight(0xfff0e0, 1.1); fill.position.set(-2, 1.5, 3.5); scene.add(fill);
    const rim = new THREE.PointLight(0xffc48a, 3.2, 14); rim.position.set(-3.4, -1.2, 2.6); scene.add(rim);
    const cool = new THREE.PointLight(0x88aaff, 1.3, 14); cool.position.set(2.6, -2.2, -2.4); scene.add(cool);

    let raf = 0, t = 0, px = 0, py = 0, tx = 0, ty = 0, running = true;
    const onPointer = (e) => {
      const r = el.getBoundingClientRect();
      tx = ((e.clientX - r.left) / r.width - 0.5) * 0.5;
      ty = ((e.clientY - r.top) / r.height - 0.5) * 0.3;
    };
    if (!mobile) el.addEventListener('pointermove', onPointer);

    const io = new IntersectionObserver(([entry]) => { running = entry.isIntersecting; }, { threshold: 0.05 });
    io.observe(el);

    const tick = () => {
      raf = requestAnimationFrame(tick);
      if (!running) return;
      t += 0.006;
      px += (tx - px) * 0.05; py += (ty - py) * 0.05;
      ball.rotation.y = t * 1.6;
      ball.rotation.z = -0.22 + Math.sin(t * 0.6) * 0.05;
      ball.position.x = Math.sin(t * 0.5) * 0.42 + px * 1.6;
      ball.position.y = 0.06 + Math.sin(t * 1.1) * 0.05 - py;
      halo.position.copy(ball.position);
      camera.position.x = px * 0.7;
      camera.lookAt(0, 0, 0);
      renderer.render(scene, camera);
    };
    tick();

    const onResize = () => {
      const nw = el.clientWidth, nh = el.clientHeight;
      camera.aspect = nw / nh; camera.updateProjectionMatrix(); renderer.setSize(nw, nh);
    };
    window.addEventListener('resize', onResize);

    return () => {
      cancelAnimationFrame(raf);
      io.disconnect();
      window.removeEventListener('resize', onResize);
      el.removeEventListener('pointermove', onPointer);
      geo.dispose(); mat.dispose(); tex.dispose(); halo.geometry.dispose(); halo.material.dispose();
      renderer.dispose();
      if (renderer.domElement.parentNode === el) el.removeChild(renderer.domElement);
    };
  }, [reduce]);

  const staticFallback = reduce || failed;
  return (
    <div aria-hidden="true" style={{ position: 'relative', height, width: '100%', pointerEvents: 'none' }}>
      <span style={{ position: 'absolute', left: '50%', top: '52%', transform: 'translate(-50%,-50%)', width: 'min(78%,520px)', aspectRatio: '1', borderRadius: '50%', background: 'radial-gradient(circle at 50% 45%, rgba(255,140,60,.30) 0%, rgba(255,120,40,.12) 45%, rgba(255,120,40,0) 72%)', filter: 'blur(2px)' }} />
      <span style={{ position: 'absolute', left: '50%', bottom: '11%', transform: 'translateX(-50%)', width: 'min(46%,300px)', height: 26, borderRadius: '50%', background: 'radial-gradient(ellipse at center, rgba(20,10,5,.22) 0%, rgba(20,10,5,0) 70%)' }} />
      {staticFallback
        ? <img src={window.ASSETS + 'sphere-static.png'} alt="" style={{ position: 'absolute', left: '50%', top: '50%', transform: 'translate(-50%,-50%)', width: 'min(60%,340px)' }} />
        : <div ref={mount} style={{ position: 'absolute', inset: 0, pointerEvents: 'auto' }} />}
    </div>
  );
}
Object.assign(window, { HeroSphere });
