// ASCII rain — runs as a fixed background across all pages.
// Calmer than the homepage hero version (lower opacity, slower) so it doesn't
// fight content on blog/about/uses/connect.

const RainBG = ({ intensity = 'calm' }) => {
  const T = window.TOKENS;
  const canvasRef = React.useRef(null);
  const [size, setSize] = React.useState({ w: window.innerWidth, h: window.innerHeight });
  const mouseRef = React.useRef({ x: 0.5, y: 0.5 });

  React.useEffect(() => {
    const onR = () => setSize({ w: window.innerWidth, h: window.innerHeight });
    const onM = (e) => { mouseRef.current = { x: e.clientX / window.innerWidth, y: e.clientY / window.innerHeight }; };
    window.addEventListener('resize', onR);
    window.addEventListener('mousemove', onM);
    return () => { window.removeEventListener('resize', onR); window.removeEventListener('mousemove', onM); };
  }, []);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    canvas.width = size.w * dpr;
    canvas.height = size.h * dpr;
    ctx.scale(dpr, dpr);

    const fontSize = 14;
    const cols = Math.floor(size.w / fontSize);
    const drops = new Array(cols).fill(0).map(() => Math.random() * size.h / fontSize);
    const speeds = drops.map(() => 0.1 + Math.random() * 0.5);
    const chars = '01░▒KAROL@LORAKSZAK<>/{}[]()|=+-_*#&%$';

    const fadeAlpha = intensity === 'hero' ? 0.10 : 0.05;
    const trailLen = intensity === 'hero' ? 24 : 48;

    let raf;
    const tick = () => {
      ctx.save();
      ctx.globalCompositeOperation = 'destination-out';
      ctx.fillStyle = `rgba(0,0,0,${fadeAlpha})`;
      ctx.fillRect(0, 0, size.w, size.h);
      ctx.restore();
      ctx.font = `${fontSize}px ${T.mono}`;

      for (let i = 0; i < cols; i++) {
        const x = i * fontSize;
        const y = drops[i] * fontSize;
        const ch = chars[Math.floor(Math.random() * chars.length)];

        const dx = (x / size.w - mouseRef.current.x);
        const dy = (y / size.h - mouseRef.current.y);
        const dist = Math.sqrt(dx * dx + dy * dy);
        const pull = Math.max(0, 1 - dist * 3);

        if (pull > 0.4) {
          ctx.fillStyle = T.rainBright;
        } else if (Math.random() < 0.015) {
          ctx.fillStyle = T.fgDim;
        } else {
          const headAlpha = intensity === 'hero' ? 0.30 : 0.15;
          const pullBoost = intensity === 'hero' ? 0.55 : 0.85;
          ctx.fillStyle = T.rainDim + (headAlpha + pull * pullBoost) + ')';
        }
        ctx.fillText(ch, x, y);

        const eraseY = (drops[i] - trailLen) * fontSize;
        if (eraseY > -fontSize) {
          ctx.clearRect(x - 1, eraseY - fontSize, fontSize + 2, fontSize + 4);
        }

        drops[i] += speeds[i];
        if (drops[i] * fontSize > size.h + trailLen * fontSize && Math.random() > 0.975) {
          drops[i] = 0;
        }
      }
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => cancelAnimationFrame(raf);
  }, [size, intensity, T]);

  return (
    <>
      <canvas ref={canvasRef} style={{
        position: 'fixed', inset: 0, width: '100%', height: '100%',
        zIndex: 0, pointerEvents: 'none',
      }} />
      <div style={{
        position: 'fixed', inset: 0, zIndex: 0, pointerEvents: 'none',
        background: intensity === 'hero'
          ? `radial-gradient(ellipse 60% 50% at 50% 50%, ${T.bg}f0 0%, ${T.bgGrad}b0 50%, transparent 100%)`
          : `linear-gradient(180deg, ${T.bg}ee 0%, ${T.bg}f8 100%)`,
      }} />
    </>
  );
};

window.RainBG = RainBG;
