// Canvas rendering for the "Beyond" atomic field.
// Pure 2D drawing helpers — no React, no state.
// Loaded as a global before beyond.jsx.

const BeyondRender = (() => {
  const BOND_DISTANCE = 220;

  function clear(ctx, dpr, w, h) {
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    ctx.clearRect(0, 0, w, h);
  }

  // Faint accent-tinted lines between nearby atoms — "covalent bonds".
  function drawBonds(ctx, particles, accentRgb) {
    const [r, g, b] = accentRgb;
    for (let i = 0; i < particles.length; i++) {
      for (let j = i + 1; j < particles.length; j++) {
        const a = particles[i];
        const c = particles[j];
        const dx = c.x - a.x;
        const dy = c.y - a.y;
        const dist = Math.hypot(dx, dy);
        const reach = BOND_DISTANCE;
        if (dist > reach) continue;
        const t = 1 - dist / reach;
        const alpha = 0.06 + t * 0.18;
        ctx.strokeStyle = `rgba(${r},${g},${b},${alpha.toFixed(3)})`;
        ctx.lineWidth = 0.6 + t * 0.8;
        ctx.beginPath();
        ctx.moveTo(a.x, a.y);
        ctx.lineTo(c.x, c.y);
        ctx.stroke();
      }
    }
  }

  function drawParticles(ctx, particles, facets, hovered, dragged, accentRgb) {
    const [ar, ag, ab] = accentRgb;
    for (let i = 0; i < particles.length; i++) {
      const p = particles[i];
      const f = facets[i];
      const active = i === hovered || i === dragged;
      const accent = f.accent === true;
      drawAtom(ctx, p, f, active, accent, ar, ag, ab);
    }
  }

  function drawAtom(ctx, p, facet, active, accent, ar, ag, ab) {
    const glowR = p.r * (active ? 1.9 : 1.5);
    const glow = ctx.createRadialGradient(p.x, p.y, p.r * 0.3, p.x, p.y, glowR);
    const glowAlpha = active ? 0.5 : 0.25;
    if (accent) {
      glow.addColorStop(0, `rgba(${ar},${ag},${ab},${glowAlpha})`);
      glow.addColorStop(1, `rgba(${ar},${ag},${ab},0)`);
    } else {
      glow.addColorStop(0, `rgba(255,255,255,${glowAlpha * 0.55})`);
      glow.addColorStop(1, 'rgba(255,255,255,0)');
    }
    ctx.fillStyle = glow;
    ctx.beginPath();
    ctx.arc(p.x, p.y, glowR, 0, Math.PI * 2);
    ctx.fill();

    const body = ctx.createRadialGradient(
      p.x - p.r * 0.4, p.y - p.r * 0.4, p.r * 0.1,
      p.x, p.y, p.r
    );
    if (accent) {
      body.addColorStop(0, `rgba(${ar},${ag},${ab},0.95)`);
      body.addColorStop(1, `rgba(${ar},${ag},${ab},0.18)`);
    } else {
      body.addColorStop(0, 'rgba(255,255,255,0.18)');
      body.addColorStop(1, 'rgba(255,255,255,0.04)');
    }
    ctx.fillStyle = body;
    ctx.beginPath();
    ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
    ctx.fill();

    ctx.strokeStyle = accent
      ? `rgba(${ar},${ag},${ab},${active ? 1 : 0.85})`
      : `rgba(255,255,255,${active ? 0.85 : 0.5})`;
    ctx.lineWidth = active ? 1.6 : 1;
    ctx.beginPath();
    ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
    ctx.stroke();

    ctx.fillStyle = accent ? '#000' : (active ? '#fff' : 'rgba(255,255,255,0.85)');
    ctx.font = `500 ${Math.round(p.r * 0.42)}px 'JetBrains Mono', ui-monospace, monospace`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(facet.n, p.x, p.y);
  }

  function hexToRgb(hex) {
    const h = hex.replace('#', '');
    return [
      parseInt(h.slice(0, 2), 16),
      parseInt(h.slice(2, 4), 16),
      parseInt(h.slice(4, 6), 16),
    ];
  }

  return { clear, drawBonds, drawParticles, hexToRgb };
})();

window.BeyondRender = BeyondRender;
