// Interactive berry + rocket canvas — sits behind the hero content.
// Drifting berries connected by faint constellation lines (the "circuit"
// motif from the logo). Click anywhere to launch a rocket from that point
// with a pixelated exhaust trail. The cursor lights up nearby berries.

const RocketCanvas = ({ density = 12 }) => {
  const canvasRef = React.useRef(null);
  const wrapRef   = React.useRef(null);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    const wrap   = wrapRef.current;
    if (!canvas || !wrap) return;

    const ctx = canvas.getContext('2d');
    const DPR = Math.min(window.devicePixelRatio || 1, 2);

    // ── State ────────────────────────────────────────────
    const PALETTE = ['#D6248C', '#A14BCC', '#7027A8', '#1F2754'];
    const berries = [];
    const rockets = [];
    const particles = [];   // mouse-trail pixels + rocket exhaust
    const mouse = { x: -9999, y: -9999, active: false };
    let W = 0, H = 0;
    let running = true, visible = true;
    let last = performance.now();

    const rand = (a, b) => a + Math.random() * (b - a);
    const pick = arr => arr[(Math.random() * arr.length) | 0];

    // ── Berry: little orb with a leaf, drifts slowly ─────
    function spawnBerry() {
      return {
        x: rand(0, W), y: rand(0, H),
        vx: rand(-0.12, 0.12), vy: rand(-0.08, 0.08),
        r: rand(5, 11),
        color: pick(PALETTE),
        wobble: rand(0, Math.PI * 2),
        wobbleSpeed: rand(0.005, 0.012),
        glow: 0,
      };
    }

    // ── Rocket: spawned on click, flies in its launch direction ──
    function spawnRocket(x, y) {
      // Direction: mostly upward, with slight outward bias from screen centre
      const cx = W / 2, cy = H / 2;
      const dx = x - cx, dy = y - cy;
      const baseAngle = -Math.PI / 2 + Math.atan2(dy, dx) * 0.15 + rand(-0.25, 0.25);
      const speed = rand(7, 10);
      rockets.push({
        x, y,
        vx: Math.cos(baseAngle) * speed,
        vy: Math.sin(baseAngle) * speed,
        angle: baseAngle,
        life: 0,
        maxLife: 180,
        color: pick(PALETTE),
        size: rand(11, 15),
      });
      // Initial spark cluster at launch point
      for (let i = 0; i < 14; i++) {
        particles.push({
          x, y,
          vx: rand(-2.5, 2.5), vy: rand(-2.5, 2.5),
          life: 1, decay: rand(0.02, 0.04),
          size: rand(2, 4),
          color: pick(PALETTE),
          kind: 'pixel',
        });
      }
    }

    // ── Sizing + canvas DPR ─────────────────────────────
    function resize() {
      const rect = wrap.getBoundingClientRect();
      W = rect.width;
      H = rect.height;
      canvas.width  = W * DPR;
      canvas.height = H * DPR;
      canvas.style.width  = W + 'px';
      canvas.style.height = H + 'px';
      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
    }

    // ── Drawing helpers ─────────────────────────────────
    function drawBerry(b) {
      const r = b.r * (1 + Math.sin(b.wobble) * 0.05);
      // Glow halo
      if (b.glow > 0) {
        const g = ctx.createRadialGradient(b.x, b.y, r * 0.4, b.x, b.y, r * 5);
        g.addColorStop(0, b.color + Math.floor(b.glow * 80).toString(16).padStart(2, '0'));
        g.addColorStop(1, b.color + '00');
        ctx.fillStyle = g;
        ctx.beginPath();
        ctx.arc(b.x, b.y, r * 5, 0, Math.PI * 2);
        ctx.fill();
      }
      // Body — gradient from logo
      const grad = ctx.createRadialGradient(b.x - r * 0.4, b.y - r * 0.4, 0, b.x, b.y, r);
      grad.addColorStop(0, b.color);
      grad.addColorStop(1, '#1F2754');
      ctx.fillStyle = grad;
      ctx.beginPath();
      ctx.arc(b.x, b.y, r, 0, Math.PI * 2);
      ctx.fill();
      // Leaves on top
      ctx.fillStyle = '#7027A8';
      ctx.beginPath();
      ctx.ellipse(b.x - r * 0.35, b.y - r * 1.1, r * 0.35, r * 0.2, -0.6, 0, Math.PI * 2);
      ctx.fill();
      ctx.beginPath();
      ctx.ellipse(b.x + r * 0.35, b.y - r * 1.1, r * 0.35, r * 0.2,  0.6, 0, Math.PI * 2);
      ctx.fill();
    }

    function drawRocket(r) {
      ctx.save();
      ctx.translate(r.x, r.y);
      ctx.rotate(r.angle + Math.PI / 2);   // ship points along velocity
      const s = r.size;
      // Body
      ctx.fillStyle = '#FFFFFF';
      ctx.beginPath();
      ctx.moveTo(0, -s);                    // nose
      ctx.bezierCurveTo(s * 0.55, -s * 0.5, s * 0.55, s * 0.4, s * 0.45, s * 0.6);
      ctx.lineTo(-s * 0.45, s * 0.6);
      ctx.bezierCurveTo(-s * 0.55, s * 0.4, -s * 0.55, -s * 0.5, 0, -s);
      ctx.fill();
      // Side fins
      ctx.fillStyle = r.color;
      ctx.beginPath();
      ctx.moveTo(-s * 0.45, s * 0.2);
      ctx.lineTo(-s * 0.9,  s * 0.85);
      ctx.lineTo(-s * 0.45, s * 0.6);
      ctx.closePath();
      ctx.fill();
      ctx.beginPath();
      ctx.moveTo( s * 0.45, s * 0.2);
      ctx.lineTo( s * 0.9,  s * 0.85);
      ctx.lineTo( s * 0.45, s * 0.6);
      ctx.closePath();
      ctx.fill();
      // Window
      ctx.fillStyle = r.color;
      ctx.beginPath();
      ctx.arc(0, -s * 0.15, s * 0.18, 0, Math.PI * 2);
      ctx.fill();
      ctx.restore();
    }

    // ── Main loop ───────────────────────────────────────
    function step(now) {
      if (!running) return;
      const dt = Math.min(now - last, 50) / 16.67;   // ≈ frames
      last = now;
      if (!visible) { requestAnimationFrame(step); return; }

      ctx.clearRect(0, 0, W, H);

      // 1. Berries: drift + edge wrap + cursor proximity glow
      for (const b of berries) {
        b.x += b.vx * dt;
        b.y += b.vy * dt;
        b.wobble += b.wobbleSpeed * dt;
        if (b.x < -20)  b.x = W + 20;
        if (b.x > W+20) b.x = -20;
        if (b.y < -20)  b.y = H + 20;
        if (b.y > H+20) b.y = -20;

        const dx = b.x - mouse.x, dy = b.y - mouse.y;
        const d2 = dx*dx + dy*dy;
        const NEAR2 = 160 * 160;
        b.glow = (mouse.active && d2 < NEAR2) ? 1 - Math.sqrt(d2) / 160 : Math.max(0, b.glow - 0.05);
      }

      // 2. Constellation lines between berries (logo's circuit motif)
      ctx.lineWidth = 1;
      for (let i = 0; i < berries.length; i++) {
        for (let j = i + 1; j < berries.length; j++) {
          const a = berries[i], c = berries[j];
          const dx = a.x - c.x, dy = a.y - c.y;
          const d2 = dx*dx + dy*dy;
          const MAX = 220;
          if (d2 < MAX * MAX) {
            const alpha = (1 - Math.sqrt(d2) / MAX) * 0.35;
            ctx.strokeStyle = `rgba(160, 75, 204, ${alpha})`;
            ctx.beginPath();
            ctx.moveTo(a.x, a.y);
            ctx.lineTo(c.x, c.y);
            ctx.stroke();
          }
        }
      }
      // Cursor-to-berry lines (only on hover)
      if (mouse.active) {
        for (const b of berries) {
          if (b.glow > 0.05) {
            ctx.strokeStyle = `rgba(214, 36, 140, ${b.glow * 0.5})`;
            ctx.beginPath();
            ctx.moveTo(mouse.x, mouse.y);
            ctx.lineTo(b.x, b.y);
            ctx.stroke();
          }
        }
      }

      // 3. Particles (pixel trail + sparks)
      for (let i = particles.length - 1; i >= 0; i--) {
        const p = particles[i];
        p.x += p.vx * dt;
        p.y += p.vy * dt;
        p.vx *= 0.96; p.vy *= 0.96;
        p.life -= p.decay * dt;
        if (p.life <= 0) { particles.splice(i, 1); continue; }
        ctx.globalAlpha = p.life;
        ctx.fillStyle = p.color;
        ctx.fillRect(p.x - p.size/2, p.y - p.size/2, p.size, p.size);
      }
      ctx.globalAlpha = 1;

      // 4. Rockets: move + emit pixel trail
      for (let i = rockets.length - 1; i >= 0; i--) {
        const r = rockets[i];
        r.x += r.vx * dt;
        r.y += r.vy * dt;
        r.life += dt;
        // Subtle gravity / drag (so it doesn't go totally straight)
        r.vx *= 0.998;
        r.vy *= 0.998;
        // Update angle to follow velocity
        r.angle = Math.atan2(r.vy, r.vx);

        // Emit exhaust opposite to velocity
        if (r.life % 1 < 0.6) {
          const back = -1;
          const ex = r.x + Math.cos(r.angle + Math.PI) * r.size * 0.5;
          const ey = r.y + Math.sin(r.angle + Math.PI) * r.size * 0.5;
          for (let k = 0; k < 2; k++) {
            particles.push({
              x: ex + rand(-2, 2), y: ey + rand(-2, 2),
              vx: -r.vx * 0.2 + rand(-0.8, 0.8),
              vy: -r.vy * 0.2 + rand(-0.8, 0.8),
              life: 1, decay: rand(0.025, 0.05),
              size: rand(2, 5),
              color: k === 0 ? r.color : pick(PALETTE),
              kind: 'pixel',
            });
          }
        }

        drawRocket(r);

        // Despawn off-screen or life exhausted
        if (r.life > r.maxLife || r.x < -60 || r.x > W + 60 || r.y < -120 || r.y > H + 60) {
          rockets.splice(i, 1);
        }
      }

      // 5. Berries draw last so they sit on top of constellation lines
      for (const b of berries) drawBerry(b);

      requestAnimationFrame(step);
    }

    // ── Listeners ───────────────────────────────────────
    function onMove(e) {
      const rect = wrap.getBoundingClientRect();
      mouse.x = (e.touches ? e.touches[0].clientX : e.clientX) - rect.left;
      mouse.y = (e.touches ? e.touches[0].clientY : e.clientY) - rect.top;
      mouse.active =
        mouse.x >= 0 && mouse.x <= W && mouse.y >= 0 && mouse.y <= H;
    }
    function onLeave() { mouse.active = false; mouse.x = -9999; mouse.y = -9999; }
    function onClick(e) {
      const rect = wrap.getBoundingClientRect();
      const x = (e.touches ? e.changedTouches[0].clientX : e.clientX) - rect.left;
      const y = (e.touches ? e.changedTouches[0].clientY : e.clientY) - rect.top;
      // Only respond if the click was within the hero
      if (x < 0 || x > W || y < 0 || y > H) return;
      if (rockets.length < 10) spawnRocket(x, y);
    }
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseleave', onLeave);
    window.addEventListener('click', onClick);
    window.addEventListener('touchstart', onClick, { passive: true });
    window.addEventListener('touchmove',  onMove,  { passive: true });

    // Pause when off-screen (perf)
    const io = new IntersectionObserver(
      (entries) => { visible = entries[0].isIntersecting; },
      { threshold: 0 }
    );
    io.observe(wrap);

    // Init
    resize();
    for (let i = 0; i < density; i++) berries.push(spawnBerry());
    window.addEventListener('resize', resize);
    requestAnimationFrame(step);

    // Demo: launch one rocket after a short delay so users see the effect
    setTimeout(() => {
      if (W > 0 && H > 0) spawnRocket(W * 0.5, H * 0.85);
    }, 1200);

    return () => {
      running = false;
      window.removeEventListener('mousemove', onMove);
      window.removeEventListener('mouseleave', onLeave);
      window.removeEventListener('click', onClick);
      window.removeEventListener('touchstart', onClick);
      window.removeEventListener('touchmove',  onMove);
      window.removeEventListener('resize', resize);
      io.disconnect();
    };
  }, [density]);

  return (
    <div ref={wrapRef} className="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
      <canvas ref={canvasRef} className="absolute inset-0 w-full h-full" style={{opacity: 0.85}}/>
      {/* Subtle hint that the canvas is interactive */}
      <div className="absolute bottom-4 right-4 font-mono text-[10px] tracking-[0.18em] uppercase opacity-60"
           style={{color: '#7027A8'}}>
        click anywhere · launch 🚀
      </div>
    </div>
  );
};

window.RocketCanvas = RocketCanvas;
