// cosmos.jsx — shared cosmic background: layered starfield + rising embers
// Exports window.CosmicBackground and window.useReducedMotion

const { useRef, useEffect } = React;

function useReducedMotion() {
  const [r, setR] = React.useState(
    typeof matchMedia !== 'undefined' && matchMedia('(prefers-reduced-motion: reduce)').matches
  );
  useEffect(() => {
    const m = matchMedia('(prefers-reduced-motion: reduce)');
    const fn = () => setR(m.matches);
    m.addEventListener('change', fn);
    return () => m.removeEventListener('change', fn);
  }, []);
  return r;
}

function CosmicBackground({ intensity = 'lively', emberHue = 36 }) {
  const canvasRef = useRef(null);
  const cfg = useRef({ intensity, emberHue });
  cfg.current = { intensity, emberHue };
  const reduced = useReducedMotion();

  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    let W = 0, H = 0, DPR = Math.min(devicePixelRatio || 1, 2);
    let stars = [], embers = [], raf = 0, t = 0;
    const mouse = { x: 0, y: 0, tx: 0, ty: 0 };
    let scrollY = window.scrollY;

    function resize() {
      W = canvas.clientWidth; H = canvas.clientHeight;
      canvas.width = W * DPR; canvas.height = H * DPR;
      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
      buildStars();
    }
    function buildStars() {
      const density = (W * H) / 6500;
      const n = Math.round(density);
      stars = [];
      for (let i = 0; i < n; i++) {
        const layer = Math.random();
        stars.push({
          x: Math.random() * W,
          y: Math.random() * (H + 600),
          z: layer,                       // depth 0..1 (parallax + size)
          r: 0.4 + layer * 1.5,
          base: 0.25 + Math.random() * 0.6,
          tw: Math.random() * Math.PI * 2, // twinkle phase
          tws: 0.6 + Math.random() * 1.6,  // twinkle speed
          warm: Math.random() < 0.18,      // a few gold stars
        });
      }
    }
    function spawnEmber() {
      // embers drift up from lower-center (the lantern campfire)
      const cx = W * (0.5 + (Math.random() - 0.5) * 0.5);
      embers.push({
        x: cx,
        y: H * (0.62 + Math.random() * 0.3),
        vx: (Math.random() - 0.5) * 0.25,
        vy: -(0.25 + Math.random() * 0.55),
        r: 0.7 + Math.random() * 1.8,
        life: 0,
        max: 160 + Math.random() * 200,
        sway: Math.random() * Math.PI * 2,
      });
    }

    function frame() {
      t += 1;
      mouse.x += (mouse.tx - mouse.x) * 0.05;
      mouse.y += (mouse.ty - mouse.y) * 0.05;
      const lively = cfg.current.intensity === 'lively';
      const hue = cfg.current.emberHue;
      ctx.clearRect(0, 0, W, H);

      // stars
      for (const s of stars) {
        const par = s.z * (lively ? 1 : 0.5);
        const px = s.x + mouse.x * 26 * par;
        const py = s.y - scrollY * 0.12 * par;
        const yy = ((py % (H + 600)) + (H + 600)) % (H + 600);
        const tw = 0.55 + 0.45 * Math.sin(s.tw + t * 0.02 * s.tws);
        const a = s.base * tw;
        ctx.beginPath();
        ctx.arc(px, yy, s.r, 0, 6.283);
        if (s.warm) ctx.fillStyle = `rgba(247,216,140,${a})`;
        else ctx.fillStyle = `rgba(196,222,236,${a})`;
        ctx.fill();
        if (s.z > 0.7) { // glow for big stars
          ctx.beginPath();
          ctx.arc(px, yy, s.r * 2.6, 0, 6.283);
          ctx.fillStyle = `rgba(${s.warm ? '247,216,140' : '150,200,230'},${a * 0.10})`;
          ctx.fill();
        }
      }

      // embers
      const cap = lively ? 90 : 40;
      const rate = lively ? 0.55 : 0.28;
      if (!reduced && embers.length < cap && Math.random() < rate) spawnEmber();
      for (let i = embers.length - 1; i >= 0; i--) {
        const e = embers[i];
        e.life++;
        e.sway += 0.03;
        e.x += e.vx + Math.sin(e.sway) * 0.3;
        e.y += e.vy - e.life * 0.0008;
        const lifeFrac = e.life / e.max;
        const a = Math.sin(lifeFrac * Math.PI) * 0.85;
        const py = e.y - scrollY * 0.06;
        ctx.beginPath();
        ctx.arc(e.x + mouse.x * 8, py, e.r, 0, 6.283);
        ctx.fillStyle = `hsla(${hue + Math.sin(e.sway) * 6}, 90%, 62%, ${a})`;
        ctx.shadowBlur = 12; ctx.shadowColor = `hsla(${hue}, 95%, 60%, ${a})`;
        ctx.fill();
        ctx.shadowBlur = 0;
        if (e.life >= e.max || py < -20) embers.splice(i, 1);
      }
      raf = requestAnimationFrame(frame);
    }

    function onMove(e) {
      mouse.tx = (e.clientX / window.innerWidth - 0.5) * 2;
      mouse.ty = (e.clientY / window.innerHeight - 0.5) * 2;
    }
    function onScroll() { scrollY = window.scrollY; }

    resize();
    window.addEventListener('resize', resize);
    window.addEventListener('mousemove', onMove, { passive: true });
    window.addEventListener('scroll', onScroll, { passive: true });
    if (reduced) {
      // static single paint
      frame(); cancelAnimationFrame(raf);
    } else {
      raf = requestAnimationFrame(frame);
    }
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('scroll', onScroll);
    };
  }, [reduced]);

  return (
    <div id="cosmos">
      <canvas id="cosmos-canvas" ref={canvasRef}></canvas>
    </div>
  );
}

window.CosmicBackground = CosmicBackground;
window.useReducedMotion = useReducedMotion;
