/* global React, THREE */
const { useState, useEffect, useRef } = React;

// ────────────────────────────────────────────────────────────
// SCENE 3D — physical-feeling render of the 4 system modules
// ────────────────────────────────────────────────────────────
function Scene3D() {
  const wrapRef = useRef(null);
  const [active, setActive] = useState(0);
  const stateRef = useRef({ targetActive: 0, blocks: [], lines: [] });

  const labels = [
    { n: '01', name: 'LEAD-REAKTIVIERUNG' },
    { n: '02', name: 'MARKETING-AUTOMATISIERUNG' },
    { n: '03', name: 'ANGEBOTE & DOKUMENTE' },
    { n: '04', name: 'MEETING-VORBEREITUNG' },
  ];

  useEffect(() => { stateRef.current.targetActive = active; }, [active]);

  useEffect(() => {
    if (!window.THREE) return;
    const mount = wrapRef.current;
    const W = mount.clientWidth, H = mount.clientHeight;

    const scene = new THREE.Scene();
    scene.background = new THREE.Color('#0d0d0d');

    const cam = new THREE.PerspectiveCamera(34, W / H, 0.1, 100);
    cam.position.set(2.4, 3.6, 7.2);
    cam.lookAt(0.3, 0.6, 0);

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.setSize(W, H);
    mount.innerHTML = '';
    mount.appendChild(renderer.domElement);

    const floorMat = new THREE.MeshStandardMaterial({
      color: '#111111', metalness: 0.7, roughness: 0.45,
    });
    const floor = new THREE.Mesh(new THREE.PlaneGeometry(40, 40), floorMat);
    floor.rotation.x = -Math.PI / 2; floor.position.y = 0;
    scene.add(floor);

    const grid = new THREE.GridHelper(40, 40, '#1e1e1e', '#1e1e1e');
    grid.position.y = 0.001;
    scene.add(grid);

    scene.add(new THREE.AmbientLight(0xffffff, 0.08));

    const spot = new THREE.SpotLight('#c8f000', 18, 22, Math.PI / 5, 0.55, 1);
    spot.position.set(6, 6, 4);
    spot.target.position.set(0, 0.6, 0);
    scene.add(spot); scene.add(spot.target);

    const BW = 1.8, BH = 0.9, BD = 1.2;
    const positions = [
      [-2.1, BH/2,  1.3],
      [ 0.2, BH/2,  0.4],
      [ 2.3, BH/2,  1.6],
      [ 0.6, BH/2 + 0.3, -1.4],
    ];

    function makeLabelTexture(idx) {
      const c = document.createElement('canvas');
      c.width = 512; c.height = 256;
      const ctx = c.getContext('2d');
      ctx.fillStyle = '#000000'; ctx.fillRect(0,0,c.width,c.height);
      ctx.fillStyle = '#dcff1e';
      ctx.font = '700 32px "Courier New", monospace';
      ctx.fillText(`// ${labels[idx].n}`, 28, 64);
      ctx.font = '700 44px "Courier New", monospace';
      const name = labels[idx].name;
      const parts = name.length > 18 ? name.split(/[\s-]/) : [name];
      let y = 120;
      parts.forEach(p => { ctx.fillText(p, 28, y); y += 46; });
      const tex = new THREE.CanvasTexture(c);
      tex.colorSpace = THREE.SRGBColorSpace;
      return tex;
    }

    const blocks = [];
    positions.forEach((p, i) => {
      const group = new THREE.Group();
      group.position.set(p[0], p[1], p[2]);

      const body = new THREE.Mesh(
        new THREE.BoxGeometry(BW, BH, BD),
        new THREE.MeshStandardMaterial({
          color: '#1a1a1a', metalness: 0.6, roughness: 0.3,
        }),
      );
      group.add(body);

      const edges = new THREE.LineSegments(
        new THREE.EdgesGeometry(body.geometry),
        new THREE.LineBasicMaterial({ color: '#c8f000', transparent: true, opacity: 0.4 }),
      );
      group.add(edges);

      const labelMesh = new THREE.Mesh(
        new THREE.PlaneGeometry(BW * 0.92, BH * 0.78),
        new THREE.MeshBasicMaterial({ map: makeLabelTexture(i), transparent: true }),
      );
      labelMesh.position.set(0, 0, BD / 2 + 0.002);
      group.add(labelMesh);

      const led = new THREE.Mesh(
        new THREE.SphereGeometry(BH * 0.08, 24, 24),
        new THREE.MeshStandardMaterial({
          color: '#c8f000', emissive: '#c8f000', emissiveIntensity: 1.0,
          metalness: 0.0, roughness: 0.4,
        }),
      );
      led.position.set(BW/2 - 0.18, BH/2 - 0.18, BD/2 + 0.02);
      group.add(led);

      if (i === 3) {
        const ped = new THREE.Mesh(
          new THREE.BoxGeometry(BW * 1.05, 0.3, BD * 1.05),
          new THREE.MeshStandardMaterial({ color: '#0f0f0f', metalness: 0.7, roughness: 0.5 }),
        );
        ped.position.y = -BH/2 - 0.15;
        group.add(ped);
      }

      scene.add(group);
      blocks.push({ group, body, edges, label: labelMesh, led, basePos: p.slice(), baseScale: 1.0 });
    });

    const pairs = [[0,1],[1,3],[2,3]];
    const lines = pairs.map(([a, b]) => {
      const pa = blocks[a].group.position.clone();
      const pb = blocks[b].group.position.clone();
      const mid = pa.clone().add(pb).multiplyScalar(0.5);
      mid.y += 0.25;
      const curve = new THREE.QuadraticBezierCurve3(pa, mid, pb);
      const geo = new THREE.TubeGeometry(curve, 24, 0.035, 8, false);
      const mat = new THREE.MeshStandardMaterial({
        color: '#c8f000', emissive: '#c8f000', emissiveIntensity: 0.6,
        transparent: true, opacity: 0.3,
        metalness: 0.0, roughness: 0.7,
      });
      const mesh = new THREE.Mesh(geo, mat);
      scene.add(mesh);
      return { mesh, mat, pair: [a, b] };
    });

    stateRef.current.blocks = blocks;
    stateRef.current.lines = lines;

    function resize() {
      const w = mount.clientWidth, h = mount.clientHeight;
      renderer.setSize(w, h);
      cam.aspect = w / h; cam.updateProjectionMatrix();
    }
    const ro = new ResizeObserver(resize);
    ro.observe(mount);

    let raf, t0 = performance.now();
    let groupRotation = 0;
    function tick() {
      const now = performance.now();
      const t = (now - t0) / 1000;

      const r = 6;
      spot.position.set(Math.cos(t * 0.35) * r, 5 + Math.sin(t * 0.2) * 0.5, Math.sin(t * 0.35) * r);

      groupRotation = t * 0.04;
      const camR = 7.6;
      cam.position.x = Math.sin(groupRotation) * camR + 0.3;
      cam.position.z = Math.cos(groupRotation) * camR;
      cam.position.y = 3.6;
      cam.lookAt(0.3, 0.7, 0);

      const target = stateRef.current.targetActive;
      blocks.forEach((b, i) => {
        const isActive = i === target;
        const desiredScale = isActive ? 1.06 : 1.0;
        const cur = b.group.scale.x;
        const ns = cur + (desiredScale - cur) * 0.12;
        b.group.scale.setScalar(ns);

        const edgeTarget = isActive ? 1.0 : 0.06;
        b.edges.material.opacity += (edgeTarget - b.edges.material.opacity) * 0.12;

        const bodyTarget = isActive ? 1.0 : 0.32;
        b.body.material.transparent = true;
        b.body.material.opacity += (bodyTarget - b.body.material.opacity) * 0.12;
        b.label.material.transparent = true;
        b.label.material.opacity = (b.label.material.opacity ?? 1) + (bodyTarget - (b.label.material.opacity ?? 1)) * 0.12;

        if (isActive) {
          const pulse = 0.4 + (Math.sin(t * 9.4) * 0.5 + 0.5) * 1.4;
          b.led.material.emissiveIntensity = pulse;
          b.led.material.opacity = 1;
        } else {
          b.led.material.emissiveIntensity += (0.0 - b.led.material.emissiveIntensity) * 0.18;
          b.led.material.transparent = true;
          b.led.material.opacity += (0.2 - b.led.material.opacity) * 0.12;
        }
      });

      lines.forEach(L => {
        const [a, b] = L.pair;
        const touchesActive = (a === target || b === target);
        const opTarget = touchesActive ? 1.0 : 0.18;
        const emTarget = touchesActive ? 1.2 : 0.25;
        L.mat.opacity += (opTarget - L.mat.opacity) * 0.12;
        L.mat.emissiveIntensity += (emTarget - L.mat.emissiveIntensity) * 0.12;
      });

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

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
      renderer.dispose();
      mount.innerHTML = '';
    };
  }, []);

  return (
    <section id="system3d" className="kat-section kat-scene-section">
      <div className="kat-section__head">
        <div>
          <div className="kat-eyebrow">03 / Module</div>
          <h2 className="kat-section__title">Dein System<br/><span className="kat-section__title--outline">in Modulen.</span></h2>
        </div>
        <p className="kat-section__intro">
          Vier Module. Ein System. Klick durch um zu sehen welches Modul gerade läuft.
          <strong> Was du nicht brauchst, wird einfach weggelassen.</strong>
        </p>
      </div>

      <div className="kat-scene">
        <div className="kat-scene__stage">
          <div ref={wrapRef} className="kat-scene__canvas"></div>
          <div className="kat-scene__status">
            <span>▮</span> AKTIV / {labels[active].name}
          </div>
          <div className="kat-scene__hint">// MODUL_VIEW / 4 SLOTS BELEGT</div>
        </div>
        <div className="kat-scene__tabs">
          {labels.map((l, i) => (
            <button key={l.n}
              className={'kat-scene__tab' + (i === active ? ' is-active' : '')}
              onClick={() => setActive(i)}>
              // {l.n}&nbsp;&nbsp;{l.name}
            </button>
          ))}
        </div>
      </div>
    </section>
  );
}

window.Scene3D = Scene3D;
