// ThreeScene — Prometheus torch surrounded by high-tech / sci-fi elements:
// concentric orbital HUD rings, a holographic ground grid, a floating
// network mesh, and a wireframe data panel — all rendered live in WebGL.

function ThreeScene({ height = 580, accent }) {
  const containerRef = React.useRef(null);
  const mouseRef     = React.useRef({ x: 0, y: 0 });

  React.useEffect(() => {
    const THREE = window.THREE;
    if (!THREE || !containerRef.current) return;
    const container = containerRef.current;
    const w = () => container.clientWidth;
    const h = () => container.clientHeight;

    const scene  = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(38, w() / h(), 0.1, 100);
    camera.position.set(0, 0.4, 9.5);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
    renderer.setSize(w(), h());
    renderer.setClearColor(0x000000, 0);
    container.appendChild(renderer.domElement);

    const ink   = 0x0a0a0a;
    const mute  = 0x9ca3af;
    const dim   = 0xd4d4d8;
    // The 3D scene is intentionally decoupled from the site's text accent.
    // Fire is orange (flame), tech is orange too — both fixed at the brand
    // flame hex. The Tweaks-driven accent controls text/UI only.
    const fire  = 0xFF6A00;
    const tech  = 0xFF6A00;

    function wire(geom, color = ink, opacity = 0.9, thresholdAngle = 1) {
      const edges = new THREE.EdgesGeometry(geom, thresholdAngle);
      const mat = new THREE.LineBasicMaterial({ color, transparent: true, opacity });
      return new THREE.LineSegments(edges, mat);
    }

    // ─── TORCH ─────────────────────────────────────────────────────────
    const torch = new THREE.Group();
    scene.add(torch);

    // Stepped plinth base
    const plinth = wire(new THREE.BoxGeometry(0.95, 0.18, 0.95), ink, 0.85);
    plinth.position.y = -2.30;
    torch.add(plinth);
    const plinth2 = wire(new THREE.BoxGeometry(0.78, 0.12, 0.78), ink, 0.85);
    plinth2.position.y = -2.14;
    torch.add(plinth2);

    // Handle shaft
    const handle = wire(new THREE.CylinderGeometry(0.16, 0.20, 1.95, 14), ink, 0.95);
    handle.position.y = -1.05;
    torch.add(handle);
    for (let i = 0; i < 3; i++) {
      const ring = wire(new THREE.TorusGeometry(0.22, 0.04, 8, 28), ink, 0.95);
      ring.rotation.x = Math.PI / 2;
      ring.position.y = -1.78 + i * 0.6;
      torch.add(ring);
    }

    // Bowl + rim
    const bowl = wire(new THREE.CylinderGeometry(0.55, 0.22, 0.55, 12), ink, 0.95);
    bowl.position.y = 0.20;
    torch.add(bowl);
    const rim = wire(new THREE.TorusGeometry(0.55, 0.05, 8, 28), ink, 0.95);
    rim.rotation.x = Math.PI / 2;
    rim.position.y = 0.48;
    torch.add(rim);

    // Flame layers
    const flameGroup = new THREE.Group();
    flameGroup.position.y = 0.55;
    torch.add(flameGroup);

    const flameOuter = wire(new THREE.ConeGeometry(0.50, 1.70, 10, 4, true), fire, 0.45, 0.3);
    flameOuter.position.y = 0.85;
    flameGroup.add(flameOuter);

    const flameMid = wire(new THREE.ConeGeometry(0.32, 1.30, 8, 3, true), fire, 0.75, 0.3);
    flameMid.position.y = 0.65;
    flameGroup.add(flameMid);

    const flameInner = wire(new THREE.ConeGeometry(0.18, 0.90, 6, 3), fire, 1.0, 0.3);
    flameInner.position.y = 0.45;
    flameGroup.add(flameInner);

    const flameCore = wire(new THREE.OctahedronGeometry(0.10, 0), fire, 1.0);
    flameCore.position.y = 0.20;
    flameGroup.add(flameCore);

    // ─── HUD ORBITAL RINGS (3 concentric, different axes & speeds) ─────
    const hudGroup = new THREE.Group();
    scene.add(hudGroup);

    const orbit1 = wire(new THREE.TorusGeometry(2.2, 0.012, 6, 96), tech, 0.85);
    orbit1.rotation.x = Math.PI / 2;
    hudGroup.add(orbit1);

    const orbit2 = wire(new THREE.TorusGeometry(2.9, 0.010, 6, 120), tech, 0.55);
    orbit2.rotation.x = Math.PI / 2 + 0.55;
    orbit2.rotation.y = 0.30;
    hudGroup.add(orbit2);

    const orbit3 = wire(new THREE.TorusGeometry(3.6, 0.008, 6, 144), tech, 0.35);
    orbit3.rotation.x = Math.PI / 2 - 0.45;
    orbit3.rotation.z = 0.35;
    hudGroup.add(orbit3);

    // Tick marks on the outer ring — small radial lines for HUD feel
    const tickGeom = new THREE.BufferGeometry();
    const tickVerts = [];
    const tickCount = 36;
    for (let i = 0; i < tickCount; i++) {
      const a  = (i / tickCount) * Math.PI * 2;
      const r0 = 3.7, r1 = i % 4 === 0 ? 3.95 : 3.80;
      tickVerts.push(Math.cos(a) * r0, 0, Math.sin(a) * r0);
      tickVerts.push(Math.cos(a) * r1, 0, Math.sin(a) * r1);
    }
    tickGeom.setAttribute("position", new THREE.Float32BufferAttribute(tickVerts, 3));
    const ticks = new THREE.LineSegments(
      tickGeom,
      new THREE.LineBasicMaterial({ color: tech, transparent: true, opacity: 0.55 })
    );
    ticks.rotation.x = -0.4;
    hudGroup.add(ticks);

    // ─── HOLO GROUND GRID (perspective floor) ──────────────────────────
    const gridGroup = new THREE.Group();
    gridGroup.position.set(0, -2.55, 0);
    scene.add(gridGroup);

    function makeGrid(size, divisions, color, opacity) {
      const g = new THREE.GridHelper(size, divisions, color, color);
      g.material.transparent = true;
      g.material.opacity = opacity;
      return g;
    }
    const gridA = makeGrid(14, 28, mute, 0.32);
    gridGroup.add(gridA);
    const gridB = makeGrid(14, 14, tech, 0.18);
    gridB.position.y = 0.001;
    gridGroup.add(gridB);

    // Faint outer ring marking the grid edge
    const groundRing = wire(new THREE.TorusGeometry(6.0, 0.008, 6, 96), mute, 0.35);
    groundRing.rotation.x = Math.PI / 2;
    groundRing.position.y = 0;
    gridGroup.add(groundRing);

    // ─── NETWORK MESH (floating data nodes + connecting lines) ─────────
    const nodes = [];
    const nodeCount = 14;
    for (let i = 0; i < nodeCount; i++) {
      const m = wire(new THREE.OctahedronGeometry(0.07, 0), tech, 0.95);
      const r = 2.8 + Math.random() * 1.6;
      const a = Math.random() * Math.PI * 2;
      const y = (Math.random() - 0.5) * 3.4;
      m.position.set(Math.cos(a) * r, y, Math.sin(a) * r - 1.2);
      m.userData = {
        phase: Math.random() * Math.PI * 2,
        bob:   0.2 + Math.random() * 0.3,
      };
      nodes.push(m);
      scene.add(m);
    }
    // Connections between nearby nodes
    const linkGeom = new THREE.BufferGeometry();
    const linkMat  = new THREE.LineBasicMaterial({ color: dim, transparent: true, opacity: 0.30 });
    const links = new THREE.LineSegments(linkGeom, linkMat);
    scene.add(links);

    function rebuildLinks() {
      const verts = [];
      const maxD = 2.4;
      for (let i = 0; i < nodes.length; i++) {
        for (let j = i + 1; j < nodes.length; j++) {
          const d = nodes[i].position.distanceTo(nodes[j].position);
          if (d < maxD) {
            verts.push(nodes[i].position.x, nodes[i].position.y, nodes[i].position.z);
            verts.push(nodes[j].position.x, nodes[j].position.y, nodes[j].position.z);
          }
        }
      }
      linkGeom.setAttribute("position", new THREE.Float32BufferAttribute(verts, 3));
      linkGeom.attributes.position.needsUpdate = true;
    }

    // ─── WIREFRAME "DATA PANEL" floating to one side (HUD readout) ─────
    function buildPanel(x, y, z, rotY) {
      const panel = new THREE.Group();
      // Frame
      const frame = wire(new THREE.PlaneGeometry(1.6, 1.0), tech, 0.85);
      panel.add(frame);
      // Inner grid
      const innerGrid = new THREE.GridHelper(1.0, 8, mute, mute);
      innerGrid.material.transparent = true;
      innerGrid.material.opacity = 0.50;
      innerGrid.rotation.x = Math.PI / 2;
      innerGrid.scale.set(1.6, 1, 1.0);
      panel.add(innerGrid);
      // Bar-chart-ish vertical ticks
      const barGeom = new THREE.BufferGeometry();
      const barVerts = [];
      for (let i = 0; i < 10; i++) {
        const xb = -0.65 + i * 0.14;
        const hb = 0.10 + Math.random() * 0.35;
        barVerts.push(xb, -0.40, 0.001);
        barVerts.push(xb, -0.40 + hb, 0.001);
      }
      barGeom.setAttribute("position", new THREE.Float32BufferAttribute(barVerts, 3));
      const bars = new THREE.LineSegments(barGeom, new THREE.LineBasicMaterial({
        color: tech, transparent: true, opacity: 0.85,
      }));
      panel.add(bars);
      panel.position.set(x, y, z);
      panel.rotation.y = rotY;
      panel.userData = { bars, bobPhase: Math.random() * Math.PI };
      return panel;
    }
    const panelL = buildPanel(-3.6,  1.20, 0.6,  0.40);
    const panelR = buildPanel( 3.6, -0.20, 0.6, -0.40);
    scene.add(panelL, panelR);

    // ─── EMBER SPARKS (rising from flame) ──────────────────────────────
    const sparks = [];
    for (let i = 0; i < 40; i++) {
      const r = 0.04 + Math.random() * 0.04;
      const s = wire(new THREE.OctahedronGeometry(r, 0), fire, 0.55 + Math.random() * 0.35);
      s.position.set(
        (Math.random() - 0.5) * 1.2,
        Math.random() * 4.5 - 0.5,
        (Math.random() - 0.5) * 1.2,
      );
      s.userData = {
        speed: 0.006 + Math.random() * 0.012,
        sway:  0.5 + Math.random() * 2.0,
        spin:  0.01 + Math.random() * 0.03,
        ox:    s.position.x,
      };
      sparks.push(s);
      scene.add(s);
    }

    // ─── ANIMATION LOOP ────────────────────────────────────────────────
    let raf;
    let linkTick = 0;
    const tick = (tMs) => {
      const t = tMs * 0.001;

      // Torch slowly orbits + bobs
      torch.rotation.y = t * 0.18;
      torch.position.y = Math.sin(t * 0.8) * 0.04;

      // Flame flicker
      flameOuter.scale.set(
        1 + Math.sin(t * 5) * 0.08,
        1 + Math.sin(t * 4 + 0.5) * 0.18,
        1 + Math.sin(t * 5.5) * 0.08,
      );
      flameOuter.rotation.y = t * 0.6;
      flameMid.scale.set(
        1 + Math.sin(t * 7 + 1) * 0.10,
        1 + Math.sin(t * 6 + 1) * 0.22,
        1 + Math.sin(t * 7 + 1) * 0.10,
      );
      flameMid.rotation.y = -t * 0.7;
      flameInner.scale.set(
        1 + Math.sin(t * 9 + 2) * 0.08,
        1 + Math.sin(t * 8 + 2) * 0.16,
        1 + Math.sin(t * 9 + 2) * 0.08,
      );
      flameInner.rotation.y = t * 0.9;
      flameCore.scale.setScalar(1 + Math.sin(t * 12) * 0.20);
      flameCore.rotation.x = t * 1.4;
      flameCore.rotation.y = t * 1.1;

      // HUD rings — orbit at different speeds & axes
      orbit1.rotation.z =  t * 0.40;
      orbit2.rotation.z = -t * 0.30;
      orbit2.rotation.x =  Math.PI / 2 + 0.55 + Math.sin(t * 0.4) * 0.10;
      orbit3.rotation.z =  t * 0.20;
      orbit3.rotation.x =  Math.PI / 2 - 0.45 + Math.cos(t * 0.3) * 0.08;
      ticks.rotation.y =  -t * 0.6;

      // Holo grid pulse
      gridB.material.opacity = 0.14 + Math.sin(t * 2.0) * 0.08;

      // Network nodes — bob & rotate
      for (const n of nodes) {
        n.position.y += Math.sin(t * n.userData.bob + n.userData.phase) * 0.003;
        n.rotation.x += 0.02;
        n.rotation.y += 0.018;
      }
      // Rebuild links every 6th frame (keeps it cheap)
      linkTick++;
      if (linkTick % 6 === 0) rebuildLinks();

      // Floating panels — gentle bob + flicker bars
      panelL.position.y = 1.20 + Math.sin(t * 0.9 + panelL.userData.bobPhase) * 0.10;
      panelR.position.y = -0.20 + Math.sin(t * 0.9 + panelR.userData.bobPhase) * 0.10;
      // Bar flicker: occasionally regenerate
      if (linkTick % 30 === 0) {
        for (const panel of [panelL, panelR]) {
          const bars = panel.userData.bars;
          const verts = [];
          for (let i = 0; i < 10; i++) {
            const xb = -0.65 + i * 0.14;
            const hb = 0.10 + Math.random() * 0.45;
            verts.push(xb, -0.40, 0.001);
            verts.push(xb, -0.40 + hb, 0.001);
          }
          bars.geometry.setAttribute("position", new THREE.Float32BufferAttribute(verts, 3));
          bars.geometry.attributes.position.needsUpdate = true;
        }
      }

      // Embers
      for (const s of sparks) {
        s.position.y += s.userData.speed;
        s.position.x = s.userData.ox + Math.sin(t * s.userData.sway + s.userData.ox) * 0.30;
        s.rotation.x += s.userData.spin;
        s.rotation.y += s.userData.spin;
        if (s.position.y > 4.2) {
          s.position.y = -0.5;
          s.position.x = (Math.random() - 0.5) * 1.2;
          s.userData.ox = s.position.x;
        }
      }

      // Mouse parallax
      const mx = mouseRef.current.x;
      const my = mouseRef.current.y;
      scene.rotation.y += (mx * 0.30 - scene.rotation.y) * 0.05;
      scene.rotation.x += (-my * 0.15 - scene.rotation.x) * 0.05;

      renderer.render(scene, camera);
      raf = requestAnimationFrame(tick);
    };
    rebuildLinks();
    raf = requestAnimationFrame(tick);

    const onMove = (e) => {
      const rect = container.getBoundingClientRect();
      mouseRef.current = {
        x: ((e.clientX - rect.left) / rect.width)  * 2 - 1,
        y: ((e.clientY - rect.top)  / rect.height) * 2 - 1,
      };
    };
    container.addEventListener("mousemove", onMove);

    const onResize = () => {
      if (!container) return;
      camera.aspect = w() / h();
      camera.updateProjectionMatrix();
      renderer.setSize(w(), h());
    };
    window.addEventListener("resize", onResize);

    return () => {
      cancelAnimationFrame(raf);
      container.removeEventListener("mousemove", onMove);
      window.removeEventListener("resize", onResize);
      renderer.dispose();
      if (renderer.domElement && renderer.domElement.parentNode === container) {
        container.removeChild(renderer.domElement);
      }
      scene.traverse((obj) => {
        if (obj.geometry) obj.geometry.dispose();
        if (obj.material) obj.material.dispose();
      });
    };
  }, [accent]);

  return (
    <div ref={containerRef} style={{
      position: "relative",
      width: "100%",
      height: height,
      borderRadius: 12,
      overflow: "hidden",
      background: "#FFFFFF",
      border: "1px solid var(--border-1)",
    }}/>
  );
}

// Section wrapper: presents the 3D scene with mono chrome + a caption.
function ThreeStudio({ accent }) {
  return (
    <section id="studio" style={{
      padding: "120px 0",
      background: "#FFFFFF",
      borderTop: "1px solid var(--border-1)",
      borderBottom: "1px solid var(--border-1)",
      position: "relative",
      overflow: "hidden",
    }}>
      <div className="container" style={{ display: "flex", flexDirection: "column", gap: 56 }}>
        <SectionHeader
          eyebrow="// STUDIO · LIVE_RENDER"
          title={<>Old fire<AccentDot /> New machinery.</>}
          sub="Promefy is from Prometheus — the bringer of new fire. Rendered live in WebGL: the torch, HUD rings, holo grid, a floating network of nodes and a live data readout. Move your cursor to tilt the scene."
        />

        <Reveal className="reveal-up">
          <div style={{ position: "relative" }}>
            <ThreeScene height={580} accent={accent} />

            {/* Corner mono markers */}
            <div style={{
              position: "absolute", left: 20, top: 20, display: "flex", gap: 8,
            }}>
              <MonoTag>WEBGL · REALTIME</MonoTag>
              <MonoTag tone="ink">PROMETHEUS_v2</MonoTag>
            </div>
            <div style={{
              position: "absolute", right: 20, top: 20,
              fontFamily: "var(--font-mono)", fontSize: 12,
              letterSpacing: "0.20em", color: "var(--fg-2)",
              textTransform: "uppercase", fontWeight: 500,
              display: "flex", alignItems: "center", gap: 8,
            }}>
              <span style={{
                width: 6, height: 6, borderRadius: "50%",
                background: "#FF6A00",
                animation: "blink 1.4s ease-in-out infinite",
              }}/>
              LIVE · 60FPS
            </div>
            <div style={{
              position: "absolute", left: 20, bottom: 20, right: 20,
              display: "flex", justifyContent: "space-between",
              fontFamily: "var(--font-mono)", fontSize: 12,
              letterSpacing: "0.18em", color: "var(--fg-2)",
              textTransform: "uppercase", fontWeight: 500,
              pointerEvents: "none",
              flexWrap: "wrap", gap: 12,
            }}>
              <span>TORCH · 3 ORBITS · HOLO_GRID · NET_MESH(14) · 40 EMBERS</span>
              <span>// MOVE TO INTERACT</span>
            </div>
          </div>
        </Reveal>
      </div>
    </section>
  );
}

Object.assign(window, { ThreeScene, ThreeStudio });
