/* VE GAMERZ — 3D hero: glassy fresnel emblem + particle field + bloom.
   Degrades to the styled fallback on reduced-motion or no-WebGL/three. */
const { useReducedMotion } = window.VG;

function hasWebGL() {
  try { const c = document.createElement('canvas'); return !!(window.WebGLRenderingContext && (c.getContext('webgl') || c.getContext('experimental-webgl'))); }
  catch (e) { return false; }
}

function Hero3D() {
  const rm = useReducedMotion();
  const mount = React.useRef(null);
  const logoRef = React.useRef(null);
  const ok = React.useRef(typeof window.THREE !== 'undefined' && hasWebGL());

  React.useEffect(() => {
    if (rm || !ok.current) return;
    const THREE = window.THREE;
    const el = mount.current;
    let W = el.clientWidth, H = el.clientHeight || 600;

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(42, W / H, 0.1, 100);
    camera.position.set(0, 0, 6.2);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, powerPreference: 'high-performance', preserveDrawingBuffer: true });
    renderer.setSize(W, H);
    renderer.setPixelRatio(Math.min(devicePixelRatio || 1, 2));
    renderer.setClearColor(0x000000, 0);
    el.appendChild(renderer.domElement);
    renderer.domElement.style.cssText = 'width:100%;height:100%;display:block;touch-action:pan-y;cursor:grab';

    const group = new THREE.Group();
    scene.add(group);

    /* Fresnel glass crystal */
    const mat = new THREE.ShaderMaterial({
      transparent: true, blending: THREE.AdditiveBlending, depthWrite: false,
      uniforms: { uEdge: { value: new THREE.Color(0x00e5ff) }, uCore: { value: new THREE.Color(0x032430) }, uPower: { value: 2.4 }, uOpacity: { value: 0.9 } },
      vertexShader: 'varying float vF; uniform float uPower; void main(){ vec4 mv=modelViewMatrix*vec4(position,1.); vec3 n=normalize(normalMatrix*normal); vec3 vd=normalize(-mv.xyz); vF=pow(1.0-abs(dot(n,vd)),uPower); gl_Position=projectionMatrix*mv; }',
      fragmentShader: 'varying float vF; uniform vec3 uEdge; uniform vec3 uCore; uniform float uOpacity; void main(){ vec3 c=mix(uCore,uEdge,clamp(vF,0.0,1.0)); gl_FragColor=vec4(c,(0.18+vF)*uOpacity); }'
    });
    const core = new THREE.Mesh(new THREE.IcosahedronGeometry(1.7, 1), mat);
    group.add(core);

    const wire = new THREE.LineSegments(
      new THREE.EdgesGeometry(new THREE.IcosahedronGeometry(1.72, 1)),
      new THREE.LineBasicMaterial({ color: 0x00e5ff, transparent: true, opacity: 0.5 })
    );
    group.add(wire);

    const innerWire = new THREE.LineSegments(
      new THREE.EdgesGeometry(new THREE.IcosahedronGeometry(1.05, 0)),
      new THREE.LineBasicMaterial({ color: 0x66f7ff, transparent: true, opacity: 0.85 })
    );
    group.add(innerWire);

    /* Particle field in a shell */
    const N = 520, pos = new Float32Array(N * 3);
    for (let i = 0; i < N; i++) {
      const r = 2.4 + Math.random() * 3.2, t = Math.random() * Math.PI * 2, p = Math.acos(2 * Math.random() - 1);
      pos[i * 3] = r * Math.sin(p) * Math.cos(t); pos[i * 3 + 1] = r * Math.sin(p) * Math.sin(t); pos[i * 3 + 2] = r * Math.cos(p);
    }
    const pg = new THREE.BufferGeometry();
    pg.setAttribute('position', new THREE.BufferAttribute(pos, 3));
    const particles = new THREE.Points(pg, new THREE.PointsMaterial({ color: 0x00e5ff, size: 0.045, transparent: true, opacity: 0.85, blending: THREE.AdditiveBlending, depthWrite: false }));
    scene.add(particles);

    scene.add(new THREE.PointLight(0x00e5ff, 1.2, 30));

    /* Your logo sits in the hollow core as a crisp DOM overlay (logoRef), positioned
       from the crystal's projected screen center in layout() — reliable load + always centered. */

    /* Optional bloom — skipped safely if any post-processing dep is missing */
    let composer = null;
    const canBloom = THREE.EffectComposer && THREE.RenderPass && THREE.UnrealBloomPass;
    if (canBloom) {
      try {
        composer = new THREE.EffectComposer(renderer);
        composer.addPass(new THREE.RenderPass(scene, camera));
        const bloom = new THREE.UnrealBloomPass(new THREE.Vector2(W, H), 0.85, 0.55, 0.15);
        composer.addPass(bloom);
        composer.setSize(W, H);
        composer.setPixelRatio(Math.min(devicePixelRatio || 1, 2));
      } catch (e) { composer = null; }
    }

    /* Size + place the emblem from the camera's visible frustum, centered in the
       actually-visible viewport (the hero can be taller than the screen) so it's
       never clipped by the fold, and kept well right of the headline. */
    const BASE_R = 1.72;
    const layout = () => {
      const halfH = Math.tan((camera.fov * Math.PI / 180) / 2) * camera.position.z;
      const halfW = halfH * camera.aspect;
      const big = W > 800;
      const targetR = halfH * (big ? 0.34 : 0.42);
      group.scale.setScalar(targetR / BASE_R);
      group.position.x = big ? halfW * 0.52 : 0;      // ~76% across on desktop
      const visible = Math.min(H, (window.innerHeight || H) - 72); // minus sticky nav
      const centerFrac = (72 + visible / 2) / H;       // where visible-center sits in the canvas
      group.position.y = big ? (0.5 - centerFrac) * 2 * halfH : halfH * 0.1;
      particles.position.x = 0;
      // pin the logo overlay into the crystal core
      const elLogo = logoRef.current;
      if (elLogo) {
        const cw = el.clientWidth, ch = el.clientHeight;
        const px = (group.position.x / (2 * halfW) + 0.5) * cw;
        const py = (0.5 - group.position.y / (2 * halfH)) * ch;
        const sizePx = (targetR * ch / halfH) * 0.46;   // ~46% of crystal diameter
        elLogo.style.left = px + 'px'; elLogo.style.top = py + 'px';
        elLogo.style.width = sizePx + 'px'; elLogo.style.height = sizePx + 'px';
        elLogo.style.opacity = '1';
      }
    };
    layout();

    /* Drag to rotate + inertia + idle auto-spin */
    let tRotX = 0.1, tRotY = 0, rotX = 0.1, rotY = 0, vX = 0, vY = 0;
    let dragging = false, lx = 0, ly = 0, idle = 0;
    const cvs = renderer.domElement;
    const down = (e) => { dragging = true; idle = 0; lx = e.clientX; ly = e.clientY; cvs.style.cursor = 'grabbing'; cvs.setPointerCapture && cvs.setPointerCapture(e.pointerId); };
    const move = (e) => {
      if (!dragging) return;
      idle = 0;
      vY = (e.clientX - lx) * 0.006; vX = (e.clientY - ly) * 0.006;
      tRotY += vY; tRotX += vX; lx = e.clientX; ly = e.clientY;
    };
    // ambient follow: sphere tilts toward the cursor from anywhere in the hero
    const ambient = (e) => {
      if (dragging) return;
      idle = 0;
      const r = cvs.getBoundingClientRect();
      const nx = ((e.clientX - r.left) / r.width) * 2 - 1;
      const ny = ((e.clientY - r.top) / r.height) * 2 - 1;
      tRotY = nx * 0.6; tRotX = 0.1 + ny * 0.42;
    };
    window.addEventListener('pointermove', ambient, { passive: true });
    const up = (e) => { dragging = false; cvs.style.cursor = 'grab'; cvs.releasePointerCapture && cvs.releasePointerCapture(e.pointerId); };
    cvs.addEventListener('pointerdown', down); cvs.addEventListener('pointermove', move);
    cvs.addEventListener('pointerup', up); cvs.addEventListener('pointercancel', up); cvs.addEventListener('pointerleave', () => { dragging = false; });

    let raf, t0 = performance.now(), stopped = false;
    const loop = (now) => {
      if (stopped) return;
      raf = requestAnimationFrame(loop);
      const dt = Math.min(0.05, (now - t0) / 1000); t0 = now; idle += dt;
      if (!dragging && idle > 1.2) tRotY += dt * 0.28;      // idle auto-spin
      rotX += (tRotX - rotX) * 0.08; rotY += (tRotY - rotY) * 0.08;
      group.rotation.x = rotX; group.rotation.y = rotY;
      core.rotation.y -= dt * 0.15; innerWire.rotation.x += dt * 0.4; innerWire.rotation.y += dt * 0.3;
      particles.rotation.y += dt * 0.03; particles.rotation.x += dt * 0.01;
      composer ? composer.render() : renderer.render(scene, camera);
    };
    raf = requestAnimationFrame(loop);

    const onResize = () => {
      W = el.clientWidth; H = el.clientHeight || 600;
      camera.aspect = W / H; camera.updateProjectionMatrix();
      renderer.setSize(W, H); composer && composer.setSize(W, H);
      layout();
    };
    window.addEventListener('resize', onResize);

    return () => {
      stopped = true; cancelAnimationFrame(raf);
      window.removeEventListener('resize', onResize);
      window.removeEventListener('pointermove', ambient);
      cvs.removeEventListener('pointerdown', down); cvs.removeEventListener('pointermove', move);
      cvs.removeEventListener('pointerup', up); cvs.removeEventListener('pointercancel', up);
      pg.dispose(); mat.dispose(); core.geometry.dispose(); wire.geometry.dispose(); innerWire.geometry.dispose();
      renderer.dispose(); if (cvs.parentNode) cvs.parentNode.removeChild(cvs);
    };
  }, [rm]);

  if (rm || !ok.current) return React.createElement(window.VGHeroFallback);
  return (
    <React.Fragment>
      {React.createElement(window.VGHeroFallback, { showEmblem: false })}
      <div ref={mount} className="vg-hero-canvas" aria-hidden="true" style={{ position: 'absolute', inset: 0, zIndex: 1 }} />
      <img ref={logoRef} src="assets/logo.jpg" alt="VE GAMERZ" style={{ position: 'absolute', left: '76%', top: '50%', width: 150, height: 150, zIndex: 3, opacity: 0, transform: 'translate(-50%,-50%)', objectFit: 'contain', mixBlendMode: 'screen', WebkitMaskImage: 'radial-gradient(circle at 50% 50%,#000 52%,rgba(0,0,0,.4) 66%,transparent 78%)', maskImage: 'radial-gradient(circle at 50% 50%,#000 52%,rgba(0,0,0,.4) 66%,transparent 78%)', filter: 'drop-shadow(0 0 16px rgba(0,229,255,.6))', pointerEvents: 'none', transition: 'opacity .5s var(--ease)' }} />
    </React.Fragment>
  );
}
window.Hero3D = Hero3D;
