// artificial-hero.jsx — Ported from artificial-hero.tsx (TypeScript → vanilla JS)
// GSAP + ScrollTrigger loaded via CDN globals. JetBrains Mono loaded in <head>.
// Scroll parallax text fixed: DOM refs updated inside RAF loop, not JSX re-render.

const ArtificialHero = () => {
  const containerRef  = React.useRef(null);
  const canvasRef     = React.useRef(null);
  const grainCanvasRef = React.useRef(null);
  const frameRef      = React.useRef(0);
  const scrollRef     = React.useRef(0);
  const timeRef       = React.useRef(0);

  // DOM refs for overlay elements — updated directly in RAF (refs don't trigger re-render)
  const textMainRef  = React.useRef(null);
  const textLeftRef  = React.useRef(null);
  const textRightRef = React.useRef(null);
  const textBotRef   = React.useRef(null);

  React.useEffect(() => {
    const canvas     = canvasRef.current;
    const grainCanvas = grainCanvasRef.current;
    if (!canvas || !grainCanvas) return;

    const ctx      = canvas.getContext('2d');
    const grainCtx = grainCanvas.getContext('2d');

    const density = ' .:-=+*#%@';

    const params = {
      rotation: 0,
      atmosphereShift: 0,
      glitchIntensity: 0,
      glitchFrequency: 0,
    };

    // ── GSAP tweens ────────────────────────────────────────────────────────
    gsap.to(params, { rotation: Math.PI * 2, duration: 20, repeat: -1, ease: 'none' });
    gsap.to(params, { atmosphereShift: 1, duration: 6, repeat: -1, yoyo: true, ease: 'sine.inOut' });
    gsap.to(params, {
      glitchIntensity: 1, duration: 0.1, repeat: -1, yoyo: true,
      ease: 'power2.inOut', repeatDelay: Math.random() * 3 + 1,
    });
    gsap.to(params, { glitchFrequency: 1, duration: 0.05, repeat: -1, yoyo: true, ease: 'none' });

    // ── ScrollTrigger ──────────────────────────────────────────────────────
    const st = ScrollTrigger.create({
      trigger: containerRef.current,
      start: 'top top',
      end: 'bottom top',
      scrub: 1,
      onUpdate: (self) => { scrollRef.current = self.progress; },
    });

    // ── Film grain ─────────────────────────────────────────────────────────
    function generateFilmGrain(w, h, intensity) {
      const imgData = grainCtx.createImageData(w, h);
      const d = imgData.data;
      for (let i = 0; i < d.length; i += 4) {
        const grain = (Math.random() - 0.5) * intensity * 255;
        const v = Math.max(0, Math.min(255, 128 + grain));
        d[i] = d[i+1] = d[i+2] = v;
        d[i+3] = Math.abs(grain) * 3;
      }
      return imgData;
    }

    // ── Glitched orb ───────────────────────────────────────────────────────
    function drawGlitchedOrb(cx, cy, radius, hue, glitchIntensity) {
      ctx.save();

      const shouldGlitch = Math.random() < 0.1 && glitchIntensity > 0.5;
      const gOff   = shouldGlitch ? (Math.random() - 0.5) * 20 * glitchIntensity : 0;
      const gScale = shouldGlitch ? 1 + (Math.random() - 0.5) * 0.3 * glitchIntensity : 1;

      if (shouldGlitch) {
        ctx.translate(gOff, gOff * 0.8);
        ctx.scale(gScale, 1 / gScale);
      }

      // Radial gradient orb
      const grad = ctx.createRadialGradient(cx, cy, 0, cx, cy, radius * 1.5);
      grad.addColorStop(0,   `hsla(${hue+10},100%,95%,0.9)`);
      grad.addColorStop(0.2, `hsla(${hue+20},90%,80%,0.7)`);
      grad.addColorStop(0.5, `hsla(${hue},70%,50%,0.4)`);
      grad.addColorStop(1,   'rgba(0,0,0,0)');
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // Bright center
      ctx.fillStyle = `hsla(${hue+20},100%,95%,0.8)`;
      ctx.beginPath();
      ctx.arc(cx, cy, radius * 0.3, 0, Math.PI * 2);
      ctx.fill();

      if (shouldGlitch) {
        ctx.globalCompositeOperation = 'screen';
        ctx.fillStyle = `hsla(100,100%,50%,${0.6 * glitchIntensity})`;
        ctx.beginPath(); ctx.arc(cx + gOff * 0.5, cy, radius * 0.3, 0, Math.PI * 2); ctx.fill();
        ctx.fillStyle = `hsla(240,100%,50%,${0.5 * glitchIntensity})`;
        ctx.beginPath(); ctx.arc(cx - gOff * 0.5, cy, radius * 0.3, 0, Math.PI * 2); ctx.fill();
        ctx.globalCompositeOperation = 'source-over';

        // Noise lines
        ctx.strokeStyle = `rgba(255,255,255,${0.6 * glitchIntensity})`;
        ctx.lineWidth = 1;
        for (let i = 0; i < 5; i++) {
          const y = cy - radius + Math.random() * radius * 2;
          ctx.beginPath();
          ctx.moveTo(cx - radius + Math.random() * 20, y);
          ctx.lineTo(cx + radius - Math.random() * 20, y);
          ctx.stroke();
        }

        // Pixel corruption blocks
        ctx.fillStyle = `rgba(255,0,255,${0.4 * glitchIntensity})`;
        for (let i = 0; i < 3; i++) {
          const bx = cx - radius + Math.random() * radius * 2;
          const by = cy - radius + Math.random() * radius * 2;
          const bs = Math.random() * 10 + 2;
          ctx.fillRect(bx, by, bs, bs);
        }
      }

      // Outer ring
      ctx.strokeStyle = `hsla(${hue+20},80%,70%,0.6)`;
      ctx.lineWidth = 2;
      if (shouldGlitch) {
        for (let i = 0; i < 8; i++) {
          const sa = (i / 8) * Math.PI * 2;
          const ea = ((i + 1) / 8) * Math.PI * 2;
          const rr = radius * 1.2 + (Math.random() - 0.5) * 10 * glitchIntensity;
          ctx.beginPath(); ctx.arc(cx, cy, rr, sa, ea); ctx.stroke();
        }
      } else {
        ctx.beginPath(); ctx.arc(cx, cy, radius * 1.2, 0, Math.PI * 2); ctx.stroke();
      }

      // Glitch bars
      if (shouldGlitch && Math.random() < 0.3) {
        ctx.globalCompositeOperation = 'difference';
        ctx.fillStyle = `rgba(255,255,255,${0.8 * glitchIntensity})`;
        for (let i = 0; i < 3; i++) {
          const by = cy - radius + Math.random() * radius * 2;
          const bh = Math.random() * 5 + 1;
          ctx.fillRect(cx - radius, by, radius * 2, bh);
        }
        ctx.globalCompositeOperation = 'source-over';
      }

      ctx.restore();
    }

    // ── Main render loop ───────────────────────────────────────────────────
    function render() {
      timeRef.current += 0.016;
      const time = timeRef.current;
      const sp   = scrollRef.current;

      const w  = canvas.width  = grainCanvas.width  = window.innerWidth;
      const h  = canvas.height = grainCanvas.height = window.innerHeight;
      const cx = w / 2;
      const cy = h / 2;
      const radius = Math.min(w, h) * 0.2;

      // Black base
      ctx.fillStyle = '#000';
      ctx.fillRect(0, 0, w, h);

      // Atmospheric bg
      const hue = 180 + params.atmosphereShift * 60;
      const bgGrad = ctx.createRadialGradient(cx, cy - 50, 0, cx, cy, Math.max(w, h) * 0.8);
      bgGrad.addColorStop(0,   `hsla(${hue+40},80%,60%,0.4)`);
      bgGrad.addColorStop(0.3, `hsla(${hue},60%,40%,0.3)`);
      bgGrad.addColorStop(0.6, `hsla(${hue-20},40%,20%,0.2)`);
      bgGrad.addColorStop(1,   'rgba(0,0,0,0.9)');
      ctx.fillStyle = bgGrad;
      ctx.fillRect(0, 0, w, h);

      // Glitched orb
      drawGlitchedOrb(cx, cy, radius, hue, params.glitchIntensity);

      // ASCII sphere
      ctx.font = '10px "JetBrains Mono", monospace';
      ctx.textAlign    = 'center';
      ctx.textBaseline = 'middle';
      const spacing = 9;
      const cols = Math.min(Math.floor(w / spacing), 150);
      const rows = Math.min(Math.floor(h / spacing), 100);

      for (let i = 0; i < cols; i++) {
        for (let j = 0; j < rows; j++) {
          const x = (i - cols / 2) * spacing + cx;
          const y = (j - rows / 2) * spacing + cy;
          const dx = x - cx;
          const dy = y - cy;
          const dist = Math.hypot(dx, dy);

          if (dist < radius && Math.random() > 0.4) {
            const z = Math.sqrt(Math.max(0, radius * radius - dx * dx - dy * dy));
            const angle = params.rotation;
            const rotZ  = dx * Math.sin(angle) + z * Math.cos(angle);
            const brightness = (rotZ + radius) / (radius * 2);

            if (rotZ > -radius * 0.3) {
              let char = density[Math.floor(brightness * (density.length - 1))];
              if (dist < radius * 0.8 && params.glitchIntensity > 0.8 && Math.random() < 0.3) {
                const gc = ['█','▓','▒','░','▄','▀','■','□'];
                char = gc[Math.floor(Math.random() * gc.length)];
              }
              ctx.fillStyle = `rgba(255,255,255,${Math.max(0.2, brightness)})`;
              ctx.fillText(char, x, y);
            }
          }
        }
      }

      // Film grain
      grainCtx.clearRect(0, 0, w, h);
      grainCtx.putImageData(generateFilmGrain(w, h, 0.22 + Math.sin(time * 10) * 0.03), 0, 0);

      if (params.glitchIntensity > 0.5) {
        grainCtx.globalCompositeOperation = 'screen';
        for (let i = 0; i < 200; i++) {
          const ox = Math.random() * w, oy = Math.random() * h;
          const os = Math.random() * 3 + 0.5;
          grainCtx.fillStyle = `rgba(255,255,255,${Math.random() * 0.5 * params.glitchIntensity})`;
          grainCtx.beginPath(); grainCtx.arc(ox, oy, os, 0, Math.PI * 2); grainCtx.fill();
        }
      }

      grainCtx.globalCompositeOperation = 'screen';
      for (let i = 0; i < 100; i++) {
        grainCtx.fillStyle = `rgba(255,255,255,${Math.random() * 0.3})`;
        grainCtx.beginPath();
        grainCtx.arc(Math.random() * w, Math.random() * h, Math.random() * 2 + 0.5, 0, Math.PI * 2);
        grainCtx.fill();
      }
      grainCtx.globalCompositeOperation = 'multiply';
      for (let i = 0; i < 50; i++) {
        grainCtx.fillStyle = `rgba(0,0,0,${Math.random() * 0.5 + 0.5})`;
        grainCtx.beginPath();
        grainCtx.arc(Math.random() * w, Math.random() * h, Math.random() * 1.5 + 0.5, 0, Math.PI * 2);
        grainCtx.fill();
      }
      grainCtx.globalCompositeOperation = 'source-over';

      // ── Update overlay DOM positions directly (bypasses missing re-render) ──
      const opFast = Math.max(0, 1 - sp * 1.5);
      const opSlow = Math.max(0, 1 - sp * 2);

      if (textMainRef.current) {
        textMainRef.current.style.transform = `translateY(${sp * 100}px)`;
        textMainRef.current.style.opacity   = opFast;
      }
      if (textLeftRef.current) {
        textLeftRef.current.style.transform = `translateX(${-sp * 200}px)`;
        textLeftRef.current.style.opacity   = opSlow;
      }
      if (textRightRef.current) {
        textRightRef.current.style.transform = `translateX(${sp * 200}px)`;
        textRightRef.current.style.opacity   = opSlow;
      }
      if (textBotRef.current) {
        textBotRef.current.style.transform = `translateY(${sp * 50}px)`;
        textBotRef.current.style.opacity   = opFast;
      }

      frameRef.current = requestAnimationFrame(render);
    }

    render();

    return () => {
      if (frameRef.current) cancelAnimationFrame(frameRef.current);
      st.kill();
      gsap.killTweensOf(params);
    };
  }, []);

  const overlayBase = {
    position: 'fixed',
    zIndex: 50,
    pointerEvents: 'none',
    willChange: 'transform, opacity',
  };

  const labelStyle = {
    fontFamily: 'Arial, sans-serif',
    fontSize: '11px',
    color: 'white',
    lineHeight: 1.4,
    letterSpacing: '0.5px',
    textTransform: 'uppercase',
    opacity: 0.8,
    maxWidth: '150px',
  };

  return (
    <div
      ref={containerRef}
      style={{ width: '100%', height: '200vh', background: '#000', position: 'relative' }}
    >
      {/* Big title */}
      <div ref={textMainRef} style={{ ...overlayBase, bottom: '15%', left: 0, right: 0 }}>
        <div style={{
          fontFamily: 'Arial Black, Arial, sans-serif',
          fontSize: 'clamp(4rem, 15vw, 12rem)',
          fontWeight: 900,
          color: 'white',
          textAlign: 'center',
          lineHeight: 0.8,
          letterSpacing: '-0.02em',
          textShadow: '0 0 50px rgba(255,255,255,0.3)',
          filter: 'contrast(1.2)',
        }}>
          ARTIFICIAL
        </div>
      </div>

      {/* Left copy */}
      <div ref={textLeftRef} style={{ ...overlayBase, left: '2rem', top: '40%' }}>
        <div style={labelStyle}>
          In the dark<br />is where<br />light takes form
        </div>
      </div>

      {/* Right copy */}
      <div ref={textRightRef} style={{ ...overlayBase, right: '2rem', top: '40%' }}>
        <div style={{ ...labelStyle, maxWidth: '150px', textAlign: 'right' }}>
          In emptiness<br />we find<br />true happiness
        </div>
      </div>

      {/* Bottom credit */}
      <div ref={textBotRef} style={{ ...overlayBase, bottom: '8%', left: '2rem' }}>
        <div style={{ ...labelStyle, fontSize: '10px', letterSpacing: '1px', opacity: 0.7 }}>
          Art direction: 21st.dev component
        </div>
      </div>

      {/* Sticky canvas container */}
      <div style={{ position: 'sticky', top: 0, width: '100%', height: '100vh' }}>
        <canvas
          ref={canvasRef}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', background: '#000' }}
        />
        <canvas
          ref={grainCanvasRef}
          style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%',
            pointerEvents: 'none', mixBlendMode: 'overlay', opacity: 0.6,
          }}
        />
      </div>

      <style>{`
        @keyframes artificial-grain {
          0%,100% { background-position: 0 0, 0 0, 0 0; }
          50%      { background-position: -5px -10px, 10px -15px, -10px 5px; }
        }
      `}</style>
    </div>
  );
};

window.ArtificialHero = ArtificialHero;
