import { useEffect, useRef } from 'react';
import { useIsMobileLayout } from '../../hooks/useMediaQuery';
import { useVisualEffects } from '../../context/VisualEffectsContext';
import './GlowParticles.css';

const PALETTE = [
  { core: 'rgba(201, 162, 39, 0.85)', mid: 'rgba(201, 162, 39, 0.25)', line: 'rgba(201, 162, 39, 0.12)' },
  { core: 'rgba(0, 245, 255, 0.75)', mid: 'rgba(0, 245, 255, 0.22)', line: 'rgba(0, 245, 255, 0.1)' },
  { core: 'rgba(255, 45, 166, 0.7)', mid: 'rgba(255, 45, 166, 0.2)', line: 'rgba(255, 45, 166, 0.09)' },
  { core: 'rgba(255, 176, 32, 0.8)', mid: 'rgba(255, 176, 32, 0.22)', line: 'rgba(255, 176, 32, 0.1)' },
] as const;

type Particle = {
  x: number;
  y: number;
  vx: number;
  vy: number;
  r: number;
  pulse: number;
  pulseSpeed: number;
  color: (typeof PALETTE)[number];
};

function particleCount(mobile: boolean): number {
  const cores = typeof navigator !== 'undefined' ? navigator.hardwareConcurrency || 4 : 4;
  if (cores <= 2) return mobile ? 18 : 28;
  if (mobile) return 32;
  return cores >= 8 ? 64 : 48;
}

function initParticles(w: number, h: number, n: number): Particle[] {
  const out: Particle[] = [];
  for (let i = 0; i < n; i++) {
    out.push({
      x: Math.random() * w,
      y: Math.random() * h,
      vx: (Math.random() - 0.5) * 0.35,
      vy: (Math.random() - 0.5) * 0.35,
      r: 1.2 + Math.random() * 2.2,
      pulse: Math.random() * Math.PI * 2,
      pulseSpeed: 0.008 + Math.random() * 0.012,
      color: PALETTE[i % PALETTE.length],
    });
  }
  return out;
}

function drawGlow(ctx: CanvasRenderingContext2D, p: Particle, alpha: number) {
  const glowR = p.r * (3.2 + Math.sin(p.pulse) * 0.8);
  const g = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, glowR);
  g.addColorStop(0, p.color.core);
  g.addColorStop(0.35, p.color.mid);
  g.addColorStop(1, 'transparent');
  ctx.save();
  ctx.globalAlpha = alpha;
  ctx.fillStyle = g;
  ctx.beginPath();
  ctx.arc(p.x, p.y, glowR, 0, Math.PI * 2);
  ctx.fill();
  ctx.restore();
}

/** Soft drifting glow orbs + faint constellation links — sits behind all UI. */
export default function GlowParticles() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const particlesRef = useRef<Particle[]>([]);
  const rafRef = useRef(0);
  const isMobile = useIsMobileLayout();
  const { glowParticles } = useVisualEffects();

  useEffect(() => {
    if (!glowParticles) return;

    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const linkDist = isMobile ? 90 : 130;
    const linkDistSq = linkDist * linkDist;

    const resize = () => {
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      const w = window.innerWidth;
      const h = window.innerHeight;
      canvas.width = Math.floor(w * dpr);
      canvas.height = Math.floor(h * dpr);
      canvas.style.width = `${w}px`;
      canvas.style.height = `${h}px`;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      particlesRef.current = initParticles(w, h, particleCount(isMobile));
    };

    resize();
    window.addEventListener('resize', resize);

    const tick = () => {
      if (document.hidden) {
        rafRef.current = requestAnimationFrame(tick);
        return;
      }

      const w = canvas.clientWidth;
      const h = canvas.clientHeight;
      ctx.clearRect(0, 0, w, h);

      const pts = particlesRef.current;
      if (!reducedMotion) {
        for (const p of pts) {
          p.x += p.vx;
          p.y += p.vy;
          p.pulse += p.pulseSpeed;
          if (p.x < -20) p.x = w + 20;
          if (p.x > w + 20) p.x = -20;
          if (p.y < -20) p.y = h + 20;
          if (p.y > h + 20) p.y = -20;
        }
      }

      for (let i = 0; i < pts.length; i++) {
        for (let j = i + 1; j < pts.length; j++) {
          const dx = pts[i].x - pts[j].x;
          const dy = pts[i].y - pts[j].y;
          const d2 = dx * dx + dy * dy;
          if (d2 < linkDistSq) {
            const t = 1 - Math.sqrt(d2) / linkDist;
            ctx.strokeStyle = pts[i].color.line;
            ctx.globalAlpha = t * 0.35;
            ctx.lineWidth = 0.6;
            ctx.beginPath();
            ctx.moveTo(pts[i].x, pts[i].y);
            ctx.lineTo(pts[j].x, pts[j].y);
            ctx.stroke();
          }
        }
      }
      ctx.globalAlpha = 1;

      for (const p of pts) {
        const twinkle = reducedMotion ? 0.75 : 0.55 + Math.sin(p.pulse) * 0.25;
        drawGlow(ctx, p, twinkle);
      }

      rafRef.current = requestAnimationFrame(tick);
    };

    rafRef.current = requestAnimationFrame(tick);

    return () => {
      window.removeEventListener('resize', resize);
      cancelAnimationFrame(rafRef.current);
    };
  }, [glowParticles, isMobile]);

  if (!glowParticles) return null;

  return (
    <>
      <canvas ref={canvasRef} className="ambient-glow-canvas" aria-hidden />
      <div className="ambient-css-sparkles" aria-hidden>
        {Array.from({ length: isMobile ? 6 : 10 }, (_, i) => (
          <span key={i} className={`ambient-sparkle ambient-sparkle--${(i % 4) + 1}`} />
        ))}
      </div>
    </>
  );
}
