/* Background scenes — canvas-based, lightweight, scrubbable. One per route. */
(function(){

function getAccent() {
  const css = getComputedStyle(document.documentElement);
  // pull oklch components
  const h = css.getPropertyValue('--accent-h').trim() || '250';
  const c = css.getPropertyValue('--accent-c').trim() || '0.18';
  const l = css.getPropertyValue('--accent-l').trim() || '0.62';
  // oklch -> approx rgb via temp element
  const probe = document.createElement('div');
  probe.style.color = `oklch(${l} ${c} ${h})`;
  document.body.appendChild(probe);
  const rgb = getComputedStyle(probe).color; // rgb(r,g,b)
  document.body.removeChild(probe);
  const m = rgb.match(/(\d+(\.\d+)?)/g);
  if (!m) return [80,140,255];
  return [parseInt(m[0]), parseInt(m[1]), parseInt(m[2])];
}

function useCanvasScene(draw) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const c = ref.current;
    if (!c) return;
    const ctx = c.getContext('2d');
    let raf, running = true;
    const dpr = Math.min(2, window.devicePixelRatio || 1);
    const resize = () => {
      const r = c.getBoundingClientRect();
      c.width = Math.max(1, r.width * dpr);
      c.height = Math.max(1, r.height * dpr);
      ctx.setTransform(dpr,0,0,dpr,0,0);
    };
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(c);
    let t0 = performance.now();
    const loop = (t) => {
      if (!running) return;
      const elapsed = (t - t0) / 1000;
      const r = c.getBoundingClientRect();
      draw(ctx, r.width, r.height, elapsed);
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => { running = false; cancelAnimationFrame(raf); ro.disconnect(); };
  }, [draw]);
  return ref;
}

/* === HOME: Big Bang — burst from center, then radial network forms === */
function HomeScene() {
  const stateRef = React.useRef(null);
  if (!stateRef.current) {
    stateRef.current = { particles: null, stars: null, last: 0 };
  }
  const ref = useCanvasScene((ctx, w, h, t) => {
    const s = stateRef.current;
    const [ar, ag, ab] = getAccent();

    if (!s.stars) {
      s.stars = Array.from({length: 180}, () => ({
        x: Math.random()*w, y: Math.random()*h,
        z: Math.random(),
        tw: Math.random()*Math.PI*2,
      }));
    }
    if (!s.particles) {
      const cx = w/2, cy = h/2;
      s.particles = Array.from({length: 220}, () => {
        const a = Math.random()*Math.PI*2;
        const sp = 0.5 + Math.random()*3.5;
        return { x: cx, y: cy, vx: Math.cos(a)*sp, vy: Math.sin(a)*sp, r: 0.6+Math.random()*1.6 };
      });
    }

    ctx.clearRect(0,0,w,h);

    // stars
    for (const st of s.stars) {
      st.tw += 0.02 + st.z*0.02;
      st.x += st.z*0.08;
      if (st.x > w+10) st.x = -10;
      const tw = 0.55 + 0.45 * Math.sin(st.tw);
      ctx.fillStyle = `rgba(220,235,255,${(0.15 + 0.45*tw) * (0.4 + st.z*0.6)})`;
      ctx.beginPath(); ctx.arc(st.x, st.y, 0.4 + st.z*1.4, 0, Math.PI*2); ctx.fill();
    }

    // central glow
    const cx = w/2, cy = h/2;
    const g = ctx.createRadialGradient(cx, cy, 0, cx, cy, Math.max(w,h)*0.45);
    g.addColorStop(0, `rgba(${ar},${ag},${ab},0.18)`);
    g.addColorStop(0.5, `rgba(${ar},${ag},${ab},0.04)`);
    g.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = g;
    ctx.fillRect(0,0,w,h);

    // burst particles drift outward, slow drag
    for (const p of s.particles) {
      p.vx *= 0.992; p.vy *= 0.992;
      p.x += p.vx; p.y += p.vy;
      // wrap if escaped
      if (p.x < -20 || p.x > w+20 || p.y < -20 || p.y > h+20) {
        p.x = cx; p.y = cy;
        const a = Math.random()*Math.PI*2;
        const sp = 0.5 + Math.random()*3.5;
        p.vx = Math.cos(a)*sp; p.vy = Math.sin(a)*sp;
      }
      const dist = Math.hypot(p.x - cx, p.y - cy);
      const fade = Math.max(0, 1 - dist / (Math.min(w,h)*0.5));
      ctx.fillStyle = `rgba(${ar},${ag},${ab},${0.35*fade + 0.1})`;
      ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, Math.PI*2); ctx.fill();
    }

    // expanding ring pulse every 6s
    const pulse = (t % 6) / 6;
    const ringR = Math.min(w,h) * (0.05 + pulse * 0.5);
    const ringA = (1 - pulse) * 0.35;
    ctx.strokeStyle = `rgba(${ar},${ag},${ab},${ringA})`;
    ctx.lineWidth = 1;
    ctx.beginPath(); ctx.arc(cx, cy, ringR, 0, Math.PI*2); ctx.stroke();

    // 12 connection lines (network) at low opacity
    ctx.strokeStyle = `rgba(${ar},${ag},${ab},0.06)`;
    ctx.lineWidth = 0.5;
    for (let i = 0; i < 12; i++) {
      const a = (i / 12) * Math.PI * 2 + t * 0.02;
      const r1 = Math.min(w,h)*0.12;
      const r2 = Math.min(w,h)*0.42;
      ctx.beginPath();
      ctx.moveTo(cx + Math.cos(a)*r1, cy + Math.sin(a)*r1);
      ctx.lineTo(cx + Math.cos(a)*r2, cy + Math.sin(a)*r2);
      ctx.stroke();
    }
  });
  return <canvas ref={ref} />;
}

/* === TRIBE: Sun + 3 orbiting pillars (Team / Tools / AI) === */
function TribeScene() {
  const stateRef = React.useRef({stars: null});
  const ref = useCanvasScene((ctx, w, h, t) => {
    const s = stateRef.current;
    const [ar, ag, ab] = getAccent();
    if (!s.stars) s.stars = Array.from({length: 140}, () => ({ x: Math.random()*w, y: Math.random()*h, z: Math.random(), tw: Math.random()*Math.PI*2 }));
    ctx.clearRect(0,0,w,h);
    for (const st of s.stars) {
      st.tw += 0.018 + st.z*0.018;
      const tw = 0.55 + 0.45 * Math.sin(st.tw);
      ctx.fillStyle = `rgba(220,235,255,${(0.12 + 0.4*tw)*(0.4+st.z*0.6)})`;
      ctx.beginPath(); ctx.arc(st.x, st.y, 0.4+st.z*1.3, 0, Math.PI*2); ctx.fill();
    }
    const cx = w/2, cy = h/2;
    // sun
    const sunR = Math.min(w,h) * 0.06;
    const sunG = ctx.createRadialGradient(cx, cy, 0, cx, cy, sunR*5);
    sunG.addColorStop(0, `rgba(${ar},${ag},${ab},0.7)`);
    sunG.addColorStop(0.2, `rgba(${ar},${ag},${ab},0.18)`);
    sunG.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = sunG;
    ctx.fillRect(0,0,w,h);
    ctx.fillStyle = `rgba(${ar},${ag},${ab},0.95)`;
    ctx.beginPath(); ctx.arc(cx, cy, sunR*0.6, 0, Math.PI*2); ctx.fill();

    // 3 orbits
    const orbits = [
      { r: Math.min(w,h)*0.18, sp: 0.25, off: 0 },
      { r: Math.min(w,h)*0.27, sp: 0.18, off: 2.1 },
      { r: Math.min(w,h)*0.36, sp: 0.13, off: 4.2 },
    ];
    ctx.strokeStyle = `rgba(${ar},${ag},${ab},0.08)`;
    ctx.lineWidth = 0.5;
    for (const o of orbits) {
      ctx.beginPath(); ctx.ellipse(cx, cy, o.r, o.r*0.45, 0, 0, Math.PI*2); ctx.stroke();
    }
    for (const o of orbits) {
      const a = t * o.sp + o.off;
      const px = cx + Math.cos(a) * o.r;
      const py = cy + Math.sin(a) * o.r * 0.45;
      const pg = ctx.createRadialGradient(px, py, 0, px, py, 24);
      pg.addColorStop(0, `rgba(${ar},${ag},${ab},0.9)`);
      pg.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = pg;
      ctx.fillRect(px-30, py-30, 60, 60);
      ctx.fillStyle = `rgba(255,255,255,0.95)`;
      ctx.beginPath(); ctx.arc(px, py, 3.5, 0, Math.PI*2); ctx.fill();
    }
  });
  return <canvas ref={ref} />;
}

/* === JANE: Pulsing AI core, concentric rings, drifting glyphs === */
function JaneScene() {
  const stateRef = React.useRef({stars:null, glyphs:null});
  const ref = useCanvasScene((ctx, w, h, t) => {
    const s = stateRef.current;
    const [ar, ag, ab] = getAccent();
    if (!s.stars) s.stars = Array.from({length:120}, () => ({x:Math.random()*w,y:Math.random()*h,z:Math.random(),tw:Math.random()*Math.PI*2}));
    if (!s.glyphs) {
      const set = ['日','月','字','A','Ω','π','я','é','字','€'];
      s.glyphs = Array.from({length: 18}, () => ({
        x: Math.random()*w, y: Math.random()*h,
        ch: set[Math.floor(Math.random()*set.length)],
        sp: 0.15 + Math.random()*0.4, op: 0.12 + Math.random()*0.18,
        sz: 14 + Math.random()*22,
      }));
    }
    ctx.clearRect(0,0,w,h);
    for (const st of s.stars) {
      st.tw += 0.018;
      const tw = 0.55 + 0.45*Math.sin(st.tw);
      ctx.fillStyle = `rgba(220,235,255,${(0.12+0.4*tw)*(0.4+st.z*0.6)})`;
      ctx.beginPath(); ctx.arc(st.x, st.y, 0.4+st.z*1.2, 0, Math.PI*2); ctx.fill();
    }
    const cx = w/2, cy = h/2;
    // core
    const pulse = 0.5 + 0.5 * Math.sin(t*1.5);
    const coreR = Math.min(w,h)*0.04 * (1 + pulse*0.2);
    const cg = ctx.createRadialGradient(cx,cy,0,cx,cy,coreR*8);
    cg.addColorStop(0, `rgba(${ar},${ag},${ab},${0.55+pulse*0.2})`);
    cg.addColorStop(0.3, `rgba(${ar},${ag},${ab},0.1)`);
    cg.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = cg; ctx.fillRect(0,0,w,h);
    ctx.fillStyle = '#fff';
    ctx.beginPath(); ctx.arc(cx, cy, coreR*0.6, 0, Math.PI*2); ctx.fill();

    // rings ripples
    for (let i = 0; i < 4; i++) {
      const phase = ((t * 0.4 + i*0.25) % 1);
      const r = phase * Math.min(w,h)*0.45;
      ctx.strokeStyle = `rgba(${ar},${ag},${ab},${(1-phase)*0.18})`;
      ctx.lineWidth = 0.8;
      ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.stroke();
    }

    // glyphs drifting
    ctx.font = '500 16px "Geist Mono", monospace';
    for (const g of s.glyphs) {
      g.y -= g.sp;
      if (g.y < -20) { g.y = h + 20; g.x = Math.random()*w; }
      ctx.fillStyle = `rgba(${ar},${ag},${ab},${g.op})`;
      ctx.font = `400 ${g.sz}px "Geist Mono", monospace`;
      ctx.fillText(g.ch, g.x, g.y);
    }
  });
  return <canvas ref={ref} />;
}

/* === MANAGED: Grid of nodes — sweeps across, lighting up === */
function ManagedScene() {
  const stateRef = React.useRef({nodes:null});
  const ref = useCanvasScene((ctx, w, h, t) => {
    const s = stateRef.current;
    const [ar, ag, ab] = getAccent();
    const cols = Math.ceil(w / 80);
    const rows = Math.ceil(h / 80);
    const stepX = w / cols;
    const stepY = h / rows;

    ctx.clearRect(0,0,w,h);

    // sweep position (moves left to right then back)
    const sweep = ((Math.sin(t*0.3) + 1) / 2) * w;

    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        const x = c * stepX + stepX/2;
        const y = r * stepY + stepY/2;
        const dist = Math.abs(x - sweep);
        const heat = Math.max(0, 1 - dist / 150);
        const baseA = 0.05;
        const a = baseA + heat * 0.45;
        ctx.fillStyle = `rgba(${ar},${ag},${ab},${a})`;
        ctx.beginPath(); ctx.arc(x, y, 1.5 + heat*2, 0, Math.PI*2); ctx.fill();
        // hairlines
        if (c < cols - 1) {
          ctx.strokeStyle = `rgba(${ar},${ag},${ab},${baseA*0.5 + heat*0.15})`;
          ctx.lineWidth = 0.5;
          ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + stepX, y); ctx.stroke();
        }
        if (r < rows - 1) {
          ctx.strokeStyle = `rgba(${ar},${ag},${ab},${baseA*0.5 + heat*0.1})`;
          ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x, y + stepY); ctx.stroke();
        }
      }
    }
  });
  return <canvas ref={ref} />;
}

/* === CONSULTING: Two paths converging into one === */
function ConsultingScene() {
  const ref = useCanvasScene((ctx, w, h, t) => {
    const [ar, ag, ab] = getAccent();
    ctx.clearRect(0,0,w,h);

    const cx = w/2, cy = h/2;

    // two paths converging at midpoint then diverging
    const drawPath = (yOffset, dir) => {
      ctx.strokeStyle = `rgba(${ar},${ag},${ab},0.25)`;
      ctx.lineWidth = 1;
      ctx.beginPath();
      for (let x = 0; x <= w; x += 4) {
        const p = x / w;
        // converge to center then merge
        const conv = Math.sin(p * Math.PI) * yOffset * dir;
        const y = cy + yOffset * dir - conv;
        if (x === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y);
      }
      ctx.stroke();
    };

    for (let i = 1; i <= 4; i++) {
      drawPath(40*i, 1);
      drawPath(40*i, -1);
    }

    // moving dots along central path
    for (let i = 0; i < 6; i++) {
      const phase = ((t * 0.15 + i/6) % 1);
      const x = phase * w;
      const y = cy;
      const op = Math.sin(phase * Math.PI);
      ctx.fillStyle = `rgba(${ar},${ag},${ab},${op*0.7})`;
      ctx.beginPath(); ctx.arc(x, y, 2.2, 0, Math.PI*2); ctx.fill();
      // glow
      const gr = ctx.createRadialGradient(x,y,0,x,y,18);
      gr.addColorStop(0, `rgba(${ar},${ag},${ab},${op*0.4})`);
      gr.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = gr; ctx.fillRect(x-20,y-20,40,40);
    }

    // central decision point
    const pulse = 0.5 + 0.5 * Math.sin(t*1.2);
    ctx.fillStyle = `rgba(${ar},${ag},${ab},${0.4+pulse*0.3})`;
    ctx.beginPath(); ctx.arc(cx, cy, 4 + pulse*2, 0, Math.PI*2); ctx.fill();
    const cg = ctx.createRadialGradient(cx,cy,0,cx,cy,80);
    cg.addColorStop(0, `rgba(${ar},${ag},${ab},${0.25 + pulse*0.15})`);
    cg.addColorStop(1, 'rgba(0,0,0,0)');
    ctx.fillStyle = cg; ctx.fillRect(cx-100, cy-100, 200, 200);
  });
  return <canvas ref={ref} />;
}

window.Scenes = { HomeScene, TribeScene, JaneScene, ManagedScene, ConsultingScene };
})();
