/* global React */
// PANTHEON immersive landing — atmosphere layers.
// EmberField: drifting gold motes + rare teal sparks (fullscreen canvas).
// CurrentCanvas: generative teal lightning bolts inside its parent.
// CursorLight: a soft divine light that follows the mouse (screen blend).

const reduceMotion = () => matchMedia('(prefers-reduced-motion: reduce)').matches;

function EmberField({ intensity = 70, current = '#36e0c8' }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (reduceMotion() || intensity <= 0) return;
    const cv = ref.current, ctx = cv.getContext('2d');
    let w, h, raf, parts = [];
    const fit = () => { w = cv.width = innerWidth; h = cv.height = innerHeight; };
    fit(); addEventListener('resize', fit);
    const N = Math.round(18 + intensity * 0.5);
    const mk = () => ({
      x: Math.random() * w, y: h + 10 + Math.random() * h * .3,
      r: .6 + Math.random() * 1.7,
      vy: .12 + Math.random() * .4, vx: (Math.random() - .5) * .16,
      a: 0, life: 0, max: 400 + Math.random() * 500,
      teal: Math.random() < .12,
    });
    for (let i = 0; i < N; i++) { const p = mk(); p.y = Math.random() * h; p.life = Math.random() * p.max; parts.push(p); }
    const tick = () => {
      ctx.clearRect(0, 0, w, h);
      for (const p of parts) {
        p.life++; p.y -= p.vy; p.x += p.vx + Math.sin((p.life + p.y) * .01) * .08;
        p.a = Math.sin(Math.min(p.life / p.max, 1) * Math.PI) * .55;
        if (p.life > p.max || p.y < -12) Object.assign(p, mk());
        ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, 7);
        ctx.fillStyle = p.teal ? current : '#e8c87e';
        ctx.globalAlpha = p.a * (p.teal ? .8 : .5);
        ctx.shadowColor = p.teal ? current : '#c9a45c';
        ctx.shadowBlur = p.teal ? 10 : 6;
        ctx.fill(); ctx.shadowBlur = 0; ctx.globalAlpha = 1;
      }
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => { cancelAnimationFrame(raf); removeEventListener('resize', fit); };
  }, [intensity, current]);
  return <canvas ref={ref} style={{ position: 'fixed', inset: 0, zIndex: 60, pointerEvents: 'none' }} aria-hidden="true" />;
}

// jagged bolt path between two points
function boltPath(ctx, x1, y1, x2, y2, jag) {
  ctx.moveTo(x1, y1);
  const segs = 14;
  let px = x1, py = y1;
  for (let i = 1; i <= segs; i++) {
    const t = i / segs;
    const nx = x1 + (x2 - x1) * t + (Math.random() - .5) * jag * (1 - t * .5);
    const ny = y1 + (y2 - y1) * t + (Math.random() - .5) * jag * .35;
    ctx.lineTo(nx, ny);
    if (Math.random() < .22 && i < segs - 2) {           // fork
      ctx.moveTo(nx, ny);
      ctx.lineTo(nx + (Math.random() - .5) * jag * 1.6, ny + 20 + Math.random() * 50);
      ctx.moveTo(nx, ny);
    }
    px = nx; py = ny;
  }
}

function CurrentCanvas({ intensity = 70, current = '#36e0c8', minDelay = 3500, maxDelay = 9000 }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (reduceMotion() || intensity <= 0) return;
    const cv = ref.current, ctx = cv.getContext('2d');
    let raf, tm, alive = true;
    const fit = () => { const r = cv.parentElement.getBoundingClientRect(); cv.width = r.width; cv.height = r.height; };
    fit(); addEventListener('resize', fit);
    const strike = () => {
      if (!alive) return;
      const w = cv.width, h = cv.height;
      const x = w * (.18 + Math.random() * .64);
      let flash = 1;
      const draw = () => {
        ctx.clearRect(0, 0, w, h);
        if (flash > .04) {
          ctx.save();
          ctx.beginPath();
          boltPath(ctx, x + (Math.random() - .5) * 30, -10, x + (Math.random() - .5) * 90, h * (.45 + Math.random() * .3), 70);
          ctx.strokeStyle = current; ctx.lineWidth = 1.4; ctx.globalAlpha = flash;
          ctx.shadowColor = current; ctx.shadowBlur = 26;
          ctx.stroke(); ctx.restore();
          // ambient flash wash
          ctx.fillStyle = current; ctx.globalAlpha = flash * .05;
          ctx.fillRect(0, 0, w, h); ctx.globalAlpha = 1;
          flash *= .78;
          raf = requestAnimationFrame(draw);
        } else { ctx.clearRect(0, 0, w, h); }
      };
      draw();
      tm = setTimeout(strike, minDelay + Math.random() * (maxDelay - minDelay) * (100 / Math.max(intensity, 20)));
    };
    tm = setTimeout(strike, 1200);
    return () => { alive = false; clearTimeout(tm); cancelAnimationFrame(raf); removeEventListener('resize', fit); };
  }, [intensity, current, minDelay, maxDelay]);
  return <canvas ref={ref} style={{ position: 'absolute', inset: 0, pointerEvents: 'none', mixBlendMode: 'screen' }} aria-hidden="true" />;
}

function CursorLight({ current = '#36e0c8' }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (reduceMotion() || !matchMedia('(pointer:fine)').matches) return;
    let tx = innerWidth / 2, ty = innerHeight * .4, x = tx, y = ty, raf;
    const onMove = e => { tx = e.clientX; ty = e.clientY; };
    addEventListener('pointermove', onMove, { passive: true });
    const tick = () => {
      x += (tx - x) * .07; y += (ty - y) * .07;
      if (ref.current) ref.current.style.background =
        `radial-gradient(420px at ${x}px ${y}px, rgba(201,164,92,.13), transparent 70%),` +
        `radial-gradient(190px at ${x}px ${y}px, ${current}14, transparent 70%)`;
      raf = requestAnimationFrame(tick);
    };
    tick();
    return () => { removeEventListener('pointermove', onMove); cancelAnimationFrame(raf); };
  }, [current]);
  return <div ref={ref} style={{ position: 'fixed', inset: 0, zIndex: 59, pointerEvents: 'none', mixBlendMode: 'screen' }} aria-hidden="true" />;
}

Object.assign(window, { EmberField, CurrentCanvas, CursorLight });
