// ======== HERO AMBIENCE ========
// Ambient particle field + live console ticker + rotating word

function ParticleField() {
  const canvasRef = React.useRef(null);
  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const setSize = () => {
      canvas.width = window.innerWidth;
      canvas.height = document.documentElement.scrollHeight;
    };
    setSize();
    let w = canvas.width;
    let h = canvas.height;
    let mouse = { x: w/2, y: h/2, active: false };

    const density = 9000;
    const N = Math.max(120, Math.min(500, Math.floor(w * h / density)));
    const particles = Array.from({length: N}, () => ({
      x: Math.random() * w,
      y: Math.random() * h,
      vx: (Math.random() - 0.5) * 0.14,
      vy: (Math.random() - 0.5) * 0.14,
      r: Math.random() * 1.4 + 0.5,
    }));

    const resize = () => {
      const oldH = h;
      canvas.width = window.innerWidth;
      canvas.height = document.documentElement.scrollHeight;
      w = canvas.width;
      h = canvas.height;
      // redistribute particles if height changed a lot
      if (Math.abs(h - oldH) > 100) {
        particles.forEach(p => {
          if (p.y > h) p.y = Math.random() * h;
          if (p.x > w) p.x = Math.random() * w;
        });
      }
    };
    window.addEventListener('resize', resize);
    // also recalc on DOMContentLoaded / after a beat to pick up final height
    const recalcT = setTimeout(resize, 500);

    const onMove = (e) => {
      mouse.x = e.clientX + window.scrollX;
      mouse.y = e.clientY + window.scrollY;
      mouse.active = true;
    };
    const onLeave = () => { mouse.active = false; };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseout', onLeave);

    let raf;
    const loop = () => {
      ctx.clearRect(0, 0, w, h);
      const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
      const ink = isDark ? '243, 241, 236' : '14, 14, 12';
      const accent = '116, 187, 95';

      particles.forEach(p => {
        p.x += p.vx; p.y += p.vy;
        if (p.x < 0) p.x = w; if (p.x > w) p.x = 0;
        if (p.y < 0) p.y = h; if (p.y > h) p.y = 0;

        if (mouse.active) {
          const dx = p.x - mouse.x;
          const dy = p.y - mouse.y;
          const d = Math.sqrt(dx*dx + dy*dy);
          if (d < 140) {
            const f = (140 - d) / 140;
            p.x += (dx / d) * f * 1.2;
            p.y += (dy / d) * f * 1.2;
          }
        }

        ctx.beginPath();
        ctx.arc(p.x, p.y, p.r, 0, Math.PI*2);
        ctx.fillStyle = `rgba(${ink}, 0.5)`;
        ctx.fill();
      });

      // only draw lines between near particles; keep it cheap
      for (let i = 0; i < particles.length; i++) {
        for (let j = i+1; j < particles.length; j++) {
          const a = particles[i], b = particles[j];
          const dx = a.x - b.x, dy = a.y - b.y;
          if (Math.abs(dx) > 110 || Math.abs(dy) > 110) continue;
          const d = Math.sqrt(dx*dx + dy*dy);
          if (d < 110) {
            const op = (1 - d/110) * 0.18;
            ctx.beginPath();
            ctx.moveTo(a.x, a.y);
            ctx.lineTo(b.x, b.y);
            ctx.strokeStyle = `rgba(${ink}, ${op})`;
            ctx.lineWidth = 0.5;
            ctx.stroke();
          }
        }
      }

      if (mouse.active) {
        const grd = ctx.createRadialGradient(mouse.x, mouse.y, 0, mouse.x, mouse.y, 90);
        grd.addColorStop(0, `rgba(${accent}, 0.16)`);
        grd.addColorStop(1, `rgba(${accent}, 0)`);
        ctx.fillStyle = grd;
        ctx.fillRect(mouse.x - 100, mouse.y - 100, 200, 200);
      }

      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);

    return () => {
      cancelAnimationFrame(raf);
      clearTimeout(recalcT);
      window.removeEventListener('resize', resize);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseout', onLeave);
    };
  }, []);

  return <canvas ref={canvasRef} className="particle-field" style={{
    position: 'absolute', top: 0, left: 0,
    width: '100%',
    pointerEvents: 'none',
    zIndex: 0,
    opacity: 1,
  }} />;
}

const CONSOLE_LINES = [
  'Deploying Wajba · build passed in 34s',
  'Nawba · 12 new appointments routed',
  'Misbar v2.1 promoted to staging',
  'Sadeem · 3 sensor alerts resolved',
  'Diwan · 41 listings indexed · KYC passed',
  'Wajba · 1,284 active orders · on-time 96%',
  'Scoping call scheduled for Thursday · 14:00 GST',
  'Pushing hotfix to main · 2 files changed',
];

function ConsoleTicker() {
  const [idx, setIdx] = React.useState(0);
  const [typed, setTyped] = React.useState('');

  React.useEffect(() => {
    const line = CONSOLE_LINES[idx];
    let i = 0;
    setTyped('');
    const typeI = setInterval(() => {
      i++;
      setTyped(line.slice(0, i));
      if (i >= line.length) clearInterval(typeI);
    }, 22);
    const next = setTimeout(() => {
      setIdx((idx + 1) % CONSOLE_LINES.length);
    }, 3600);
    return () => { clearInterval(typeI); clearTimeout(next); };
  }, [idx]);

  return (
    <div className="hero-console" aria-hidden>
      <span className="hero-console-dot" />
      <span className="hero-console-prompt">&gt;</span>
      <span className="hero-console-text">{typed}</span>
      <span className="hero-console-caret">_</span>
    </div>
  );
}

function RotatingWord({ words, interval = 2400 }) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    const t = setInterval(() => setI(x => (x + 1) % words.length), interval);
    return () => clearInterval(t);
  }, [words, interval]);
  return (
    <span className="rotating-word">
      {words.map((w, idx) => (
        <span key={idx} className={`rotating-word-slot ${idx === i ? 'active' : ''}`}>
          <span className="serif">{w}</span>
        </span>
      ))}
    </span>
  );
}

Object.assign(window, { ParticleField, ConsoleTicker, RotatingWord });
