// =====================================================
// TACTICAL FX — niche-gamer interactive background layer
// Bullet impacts, spark bursts, sonar pings, wallhack glow
// =====================================================

const { useEffect, useRef } = React;

function ImpactFX({ mode = 'bullets', wallhack = false }) {
  const canvasRef = useRef(null);
  const decalRef = useRef(null);

  useEffect(() => {
    document.documentElement.classList.toggle('wallhack', wallhack);
  }, [wallhack]);

  useEffect(() => {
    if (mode === 'off') return;
    const canvas = canvasRef.current;
    const decal = decalRef.current;
    const ctx = canvas.getContext('2d');
    const dctx = decal.getContext('2d');
    let dpr = Math.min(window.devicePixelRatio || 1, 2);
    let w, h;
    const resize = () => {
      w = window.innerWidth; h = window.innerHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      canvas.style.width = w + 'px'; canvas.style.height = h + 'px';
      decal.width = w * dpr; decal.height = h * dpr;
      decal.style.width = w + 'px'; decal.style.height = h + 'px';
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      dctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    };
    resize();
    window.addEventListener('resize', resize);

    const sparks = [];      // line particles
    const dust = [];        // small dust circles
    const rings = [];       // sonar rings
    const decals = [];      // {x,y,life,maxLife} bullet holes (drawn each frame to decal canvas with alpha decay)

    const rand = (a, b) => a + Math.random() * (b - a);

    const spawnBullet = (x, y) => {
      // 1) impact decal — drawn ONCE to decal canvas (persists, fades)
      decals.push({ x, y, life: 1.0, born: performance.now() });

      // 2) spark burst — 14-18 fast lines
      const n = 14 + Math.floor(Math.random() * 5);
      for (let i = 0; i < n; i++) {
        const angle = Math.random() * Math.PI * 2;
        const speed = rand(2.4, 6.2);
        sparks.push({
          x, y,
          vx: Math.cos(angle) * speed,
          vy: Math.sin(angle) * speed - 0.4, // bias up
          life: 1, decay: rand(0.025, 0.05),
          len: rand(4, 9),
          color: Math.random() < 0.7 ? '#f0c060' : (Math.random() < 0.5 ? '#ffe9a8' : '#c8621a')
        });
      }

      // 3) concrete dust — slow drifting particles
      for (let i = 0; i < 18; i++) {
        const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
        const speed = rand(0.3, 1.6);
        dust.push({
          x, y,
          vx: Math.cos(angle) * speed,
          vy: Math.sin(angle) * speed,
          life: 1, decay: rand(0.008, 0.018),
          r: rand(0.6, 1.8),
          color: Math.random() < 0.5 ? '#6a7382' : '#3a4250'
        });
      }
    };

    const spawnSonar = (x, y) => {
      rings.push({ x, y, r: 0, life: 1 });
      rings.push({ x, y, r: 0, life: 1, delay: 80, _born: performance.now() });
      rings.push({ x, y, r: 0, life: 1, delay: 160, _born: performance.now() });
    };

    const onClick = (e) => {
      // Don't fire when clicking on interactive UI
      const tag = e.target.tagName;
      if (tag === 'A' || tag === 'BUTTON' || tag === 'INPUT') return;
      if (e.target.closest('.twk-panel, .console, .nav-link, .weapon, .social, .arsenal-cat, .radar-dot, .cta')) return;
      const x = e.clientX, y = e.clientY;
      if (mode === 'bullets') spawnBullet(x, y);
      else if (mode === 'sonar') spawnSonar(x, y);
      else if (mode === 'sparks') {
        // sparks only, no decal
        for (let i = 0; i < 22; i++) {
          const angle = Math.random() * Math.PI * 2;
          const speed = rand(3, 7);
          sparks.push({
            x, y,
            vx: Math.cos(angle) * speed,
            vy: Math.sin(angle) * speed - 0.4,
            life: 1, decay: rand(0.02, 0.04),
            len: rand(5, 10),
            color: Math.random() < 0.6 ? '#f0c060' : '#ffe9a8'
          });
        }
      }
    };
    window.addEventListener('click', onClick);
    window.__fxClear = () => {
      dctx.save();
      dctx.setTransform(1, 0, 0, 1, 0, 0);
      dctx.clearRect(0, 0, decal.width, decal.height);
      dctx.restore();
      decals.length = 0;
      sparks.length = 0;
      dust.length = 0;
      rings.length = 0;
    };
    const onKeyDown = (e) => {
      if (e.key === 'Control' || e.key === 'Meta') { window.__fxClear?.(); }
    };
    window.addEventListener('keydown', onKeyDown);

    // Draw fresh decals to decal canvas
    const renderDecal = (d) => {
      const { x, y } = d;
      dctx.save();
      // Dark inner hole
      dctx.fillStyle = 'rgba(8, 11, 15, 0.85)';
      dctx.beginPath(); dctx.arc(x, y, 3.2, 0, Math.PI * 2); dctx.fill();
      // Ring crack
      dctx.strokeStyle = 'rgba(8, 11, 15, 0.65)';
      dctx.lineWidth = 1;
      dctx.beginPath(); dctx.arc(x, y, 5.5, 0, Math.PI * 2); dctx.stroke();
      // Radial crack lines
      const cracks = 5 + Math.floor(Math.random() * 4);
      for (let i = 0; i < cracks; i++) {
        const a = (i / cracks) * Math.PI * 2 + Math.random() * 0.5;
        const len = 4 + Math.random() * 10;
        dctx.strokeStyle = 'rgba(8, 11, 15, ' + (0.45 + Math.random() * 0.3) + ')';
        dctx.lineWidth = 0.8;
        dctx.beginPath();
        dctx.moveTo(x + Math.cos(a) * 3, y + Math.sin(a) * 3);
        dctx.lineTo(x + Math.cos(a) * (3 + len), y + Math.sin(a) * (3 + len));
        dctx.stroke();
      }
      // Tiny gold rim spark
      dctx.strokeStyle = 'rgba(212, 168, 67, 0.4)';
      dctx.lineWidth = 0.6;
      dctx.beginPath(); dctx.arc(x, y, 4, 0, Math.PI * 2); dctx.stroke();
      dctx.restore();
      d.rendered = true;
    };

    let raf;
    const tick = () => {
      ctx.clearRect(0, 0, w, h);

      // Decal slow fade — every ~30 frames, slightly darken-clear the decal canvas
      // Use a tiny global alpha clear to age impacts over ~30s
      dctx.save();
      dctx.globalCompositeOperation = 'destination-out';
      dctx.fillStyle = 'rgba(0,0,0,0.004)';
      dctx.fillRect(0, 0, w, h);
      dctx.restore();

      // Render any new decals
      for (const d of decals) {
        if (!d.rendered) renderDecal(d);
      }

      // Sparks
      for (let i = sparks.length - 1; i >= 0; i--) {
        const s = sparks[i];
        s.x += s.vx; s.y += s.vy;
        s.vx *= 0.94; s.vy *= 0.94;
        s.vy += 0.15; // gravity
        s.life -= s.decay;
        if (s.life <= 0) { sparks.splice(i, 1); continue; }
        ctx.globalAlpha = s.life;
        ctx.strokeStyle = s.color;
        ctx.lineWidth = 1.4;
        ctx.beginPath();
        ctx.moveTo(s.x, s.y);
        ctx.lineTo(s.x - s.vx * s.len * 0.35, s.y - s.vy * s.len * 0.35);
        ctx.stroke();
      }

      // Dust
      for (let i = dust.length - 1; i >= 0; i--) {
        const p = dust[i];
        p.x += p.vx; p.y += p.vy;
        p.vy += 0.04; // gravity
        p.vx *= 0.985;
        p.life -= p.decay;
        if (p.life <= 0) { dust.splice(i, 1); continue; }
        ctx.globalAlpha = p.life * 0.5;
        ctx.fillStyle = p.color;
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
        ctx.fill();
      }

      // Sonar rings
      const now = performance.now();
      for (let i = rings.length - 1; i >= 0; i--) {
        const r = rings[i];
        if (r.delay && r._born && now - r._born < r.delay) continue;
        r.r += 3.4;
        r.life -= 0.012;
        if (r.life <= 0) { rings.splice(i, 1); continue; }
        ctx.globalAlpha = r.life;
        ctx.strokeStyle = '#3dd870';
        ctx.lineWidth = 1.2;
        ctx.beginPath();
        ctx.arc(r.x, r.y, r.r, 0, Math.PI * 2);
        ctx.stroke();
        // inner glow ring
        ctx.globalAlpha = r.life * 0.4;
        ctx.lineWidth = 4;
        ctx.beginPath();
        ctx.arc(r.x, r.y, r.r, 0, Math.PI * 2);
        ctx.stroke();
      }

      ctx.globalAlpha = 1;
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener('resize', resize);
      window.removeEventListener('click', onClick);
      window.removeEventListener('keydown', onKeyDown);
      delete window.__fxClear;
    };
  }, [mode]);

  if (mode === 'off') return null;
  return (
    <>
      <canvas ref={decalRef} className="fx-decals" />
      <canvas ref={canvasRef} className="fx-active" />
    </>
  );
}

window.ImpactFX = ImpactFX;
