/* ============================================================
   PETRI GAMES — Infinity field + petri visuals
   The ∞ "microcurrents" spine that flows behind every page.
   ============================================================ */

// deterministic pseudo-random so layouts are stable across renders
function rng(seed) {
  let s = seed % 2147483647;
  if (s <= 0) s += 2147483646;
  return () => (s = (s * 16807) % 2147483647) / 2147483647;
}

// Respect the OS "reduce motion" setting. SMIL (<animate>/<animateMotion>) cannot
// be stopped by CSS, so we gate it here in JS and render a calm static state instead.
function usePrefersReducedMotion() {
  const get = () =>
    typeof window !== 'undefined' && window.matchMedia
      ? window.matchMedia('(prefers-reduced-motion: reduce)').matches
      : false;
  const [reduced, setReduced] = React.useState(get);
  React.useEffect(() => {
    const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
    const on = () => setReduced(mq.matches);
    mq.addEventListener ? mq.addEventListener('change', on) : mq.addListener(on);
    return () => (mq.removeEventListener ? mq.removeEventListener('change', on) : mq.removeListener(on));
  }, []);
  return reduced;
}

// A single (x,y) on the Gerono lemniscate — used to park currents when motion is off.
function lemniscatePoint(cx, cy, a, b, t) {
  return { x: cx + a * Math.cos(t), y: cy + b * Math.sin(t) * Math.cos(t) };
}

// ---- Microcurrent dots that ride the ∞ path via SMIL animateMotion ----
const CURRENTS = [
  { dur: 13, begin: 0,    r: 3.4, cls: '' },
  { dur: 13, begin: -3.2, r: 2.2, cls: 'is-yellow' },
  { dur: 13, begin: -6.5, r: 4,   cls: '' },
  { dur: 13, begin: -9.8, r: 2.6, cls: 'is-orange' },
  { dur: 19, begin: -2,   r: 2.8, cls: '' },
  { dur: 19, begin: -8,   r: 3.6, cls: 'is-yellow' },
  { dur: 19, begin: -14,  r: 2.2, cls: '' },
  { dur: 9,  begin: -1.5, r: 2,   cls: 'is-orange' },
  { dur: 9,  begin: -5.5, r: 2.8, cls: '' },
  { dur: 24, begin: -4,   r: 4.4, cls: '' },
  { dur: 24, begin: -16,  r: 2.4, cls: 'is-yellow' },
];

function InfinityField({ seed = 7 }) {
  // drifting "cells" + soft blobs (DOM layer)
  const r = rng(seed);
  const cells = Array.from({ length: 16 }, () => ({
    left: (r() * 100).toFixed(1) + '%',
    top: (r() * 100).toFixed(1) + '%',
    size: (4 + r() * 12).toFixed(0),
    dur: (9 + r() * 12).toFixed(1),
    delay: (-r() * 12).toFixed(1),
    op: (0.12 + r() * 0.28).toFixed(2),
    tint: ['var(--accent)', 'var(--exp-orange)', 'var(--lab-yellow)', 'var(--ink-soft)'][Math.floor(r() * 4)],
  }));

  const blobs = [
    { left: '12%', top: '18%', size: 380, color: 'var(--accent)', dur: 26 },
    { left: '78%', top: '60%', size: 440, color: 'var(--exp-orange)', dur: 34 },
    { left: '40%', top: '82%', size: 320, color: 'var(--lab-yellow)', dur: 30 },
  ];

  return (
    <div className="inf-field" aria-hidden="true">
      <div className="inf-grid" />
      {blobs.map((bl, i) => (
        <div key={i} className="inf-blob" style={{
          left: bl.left, top: bl.top, width: bl.size, height: bl.size,
          marginLeft: -bl.size / 2, marginTop: -bl.size / 2,
          background: bl.color, animationDuration: bl.dur + 's',
          animationDelay: (-i * 4) + 's',
        }} />
      ))}

      {cells.map((c, i) => (
        <div key={i} className="cell" style={{
          left: c.left, top: c.top, width: c.size + 'px', height: c.size + 'px',
          background: c.tint, opacity: c.op,
          boxShadow: `0 0 calc(10px * var(--glow)) ${c.tint}`,
          animationDuration: c.dur + 's', animationDelay: c.delay + 's',
        }} />
      ))}
    </div>
  );
}

// ---- Abstract petri-dish visual (per project) ----
function PetriDish({ seed = 1, accentCell = 'var(--lime-glow)', count = 13, big = false }) {
  const r = rng(seed * 97 + 5);
  const cells = Array.from({ length: count }, () => {
    const ang = r() * Math.PI * 2;
    const rad = Math.sqrt(r()) * 40;          // bias toward center
    const palette = [accentCell, 'var(--exp-orange)', 'var(--lab-yellow)', 'var(--lime-glow)', 'var(--ink-soft)'];
    return {
      left: (50 + Math.cos(ang) * rad).toFixed(1) + '%',
      top: (50 + Math.sin(ang) * rad).toFixed(1) + '%',
      size: (5 + r() * (big ? 30 : 20)).toFixed(0),
      tint: r() < 0.55 ? accentCell : palette[Math.floor(r() * palette.length)],
      op: (0.45 + r() * 0.5).toFixed(2),
      dur: (7 + r() * 9).toFixed(1),
      delay: (-r() * 9).toFixed(1),
      ring: r() < 0.4,
    };
  });
  return (
    <div className="dish">
      {cells.map((c, i) => (
        <div key={i} className="cell" style={{
          left: c.left, top: c.top, width: c.size + 'px', height: c.size + 'px',
          transform: 'translate(-50%,-50%)',
          background: c.ring ? 'transparent' : c.tint,
          border: c.ring ? `1.5px solid ${c.tint}` : 'none',
          opacity: c.op,
          boxShadow: `0 0 calc(12px * var(--glow)) ${c.tint}`,
          animationDuration: c.dur + 's', animationDelay: c.delay + 's',
        }} />
      ))}
    </div>
  );
}

// ---- Petri Games logo mark (petri dish + awakened-cell eye) ----
// The eye = white cell with a dark pupil + thin dark outline so it reads on
// BOTH the dark nav and the light theme/footer. Spore colonies use the brand
// palette (lime / green / yellow / warm) to echo the dishes across the site.
function PetriMark() {
  return (
    <svg viewBox="0 0 30 30" className="brand-mark-svg">
      <circle cx="15" cy="15" r="13" fill="none" stroke="var(--ink-soft)" strokeWidth="1.8" />
      {/* spore colonies */}
      <circle cx="21.4" cy="9.2" r="1.5" fill="#B6F23A" />
      <circle cx="8.4" cy="11" r="1.05" fill="#9FE32E" />
      <circle cx="20.4" cy="20.8" r="1.2" fill="#B6F23A" opacity="0.9" />
      <circle cx="12.6" cy="8.3" r="0.7" fill="#F4CE3F" />
      <circle cx="7.8" cy="20.2" r="0.7" fill="#F2682E" />
      {/* awakened-cell eye */}
      <circle cx="14.2" cy="16.2" r="3.6" fill="#FCFBF2" stroke="var(--ink-soft)" strokeWidth="0.6" />
      <circle cx="14.7" cy="15.7" r="1.7" fill="#10130A" />
      <circle cx="13.9" cy="14.9" r="0.55" fill="#FCFBF2" />
    </svg>
  );
}

Object.assign(window, { InfinityField, PetriDish, PetriMark, rng });
