import { useEffect, useRef } from 'react';

interface Particle { x: number; y: number; z: number; r: number; tw: number; ts: number; }

export function AuthBackground() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const knowledgeRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const canvasEl = canvasRef.current;
    if (!canvasEl) return;
    const ctx2d = canvasEl.getContext('2d');
    if (!ctx2d) return;
    const canvas: HTMLCanvasElement = canvasEl;
    const ctx: CanvasRenderingContext2D = ctx2d;

    const reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    let W = 0;
    let H = 0;
    let yaw = 0;
    let targetYaw = 0;
    const particles: Particle[] = [];

    function buildParticles() {
      particles.length = 0;
      const count = Math.max(30, Math.min(90, Math.round((W * H) / 18000)));
      for (let i = 0; i < count; i++) {
        particles.push({
          x: (Math.random() - 0.5) * 2,
          y: (Math.random() - 0.5) * 2,
          z: (Math.random() - 0.5) * 2,
          r: Math.random() * 1.3 + 0.3,
          tw: Math.random() * Math.PI * 2,
          ts: 0.3 + Math.random() * 1,
        });
      }
    }

    function resize() {
      const rect = canvas.getBoundingClientRect();
      W = rect.width;
      H = rect.height;
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      canvas.width = Math.max(1, Math.round(W * dpr));
      canvas.height = Math.max(1, Math.round(H * dpr));
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      buildParticles();
      if (reduced) draw(performance.now());
    }

    function onPointerMove(e: PointerEvent) {
      const rect = canvas.getBoundingClientRect();
      const nx = (e.clientX - rect.left) / rect.width - 0.5;
      const ny = (e.clientY - rect.top) / rect.height - 0.5;
      targetYaw = nx * 0.7;
      knowledgeRef.current?.style.setProperty('--al-scene-x', `${nx * 18}px`);
      knowledgeRef.current?.style.setProperty('--al-scene-y', `${ny * 12}px`);
      knowledgeRef.current?.style.setProperty('--al-scene-ry', `${nx * 3}deg`);
      knowledgeRef.current?.style.setProperty('--al-scene-rx', `${ny * -2}deg`);
    }

    let raf = 0;
    let last = performance.now();
    const running = !reduced;

    function draw(now: number) {
      if (W < 2 || H < 2) {
        if (running) raf = requestAnimationFrame(draw);
        return;
      }
      const dt = Math.min(0.05, (now - last) / 1000);
      last = now;

      yaw += (targetYaw - yaw) * 0.05;
      if (running) yaw += dt * 0.08;

      const cyaw = Math.cos(yaw);
      const syaw = Math.sin(yaw);

      const cx = W / 2;
      const cy = H / 2;
      const F = Math.min(W, H) * 1.2;
      const R = Math.min(W, H) * 0.32;

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

      // particles
      for (const p of particles) {
        if (running) p.tw += dt * p.ts;
        const px = p.x * cyaw + p.z * syaw;
        const pz = -p.x * syaw + p.z * cyaw;
        const pScale = F / (F - pz * R * 0.6);
        const sx = cx + px * R * 1.8 * pScale;
        const sy = cy + p.y * R * 1.8 * pScale;
        const a = (0.08 + 0.35 * (0.5 + 0.5 * Math.sin(p.tw))) * (0.4 + 0.6 * (0.5 + 0.5 * pz));
        ctx.beginPath();
        ctx.arc(sx, sy, p.r * pScale, 0, Math.PI * 2);
        ctx.fillStyle = `rgba(180, 235, 220, ${a})`;
        ctx.fill();
      }

      // orbital rings
      const rings = [{ incl: 0.0, rad: 1.0 }, { incl: 0.5, rad: 1.18 }];
      for (const ring of rings) {
        ctx.beginPath();
        const steps = 72;
        for (let i = 0; i <= steps; i++) {
          const t = (i / steps) * Math.PI * 2;
          const lx = Math.cos(t) * R * ring.rad;
          const ly = -Math.sin(t) * Math.sin(ring.incl) * R * ring.rad;
          const lz = Math.sin(t) * Math.cos(ring.incl) * R * ring.rad;
          const rx = lx * cyaw + lz * syaw;
          const rz = -lx * syaw + lz * cyaw;
          const pScale = F / (F - rz);
          const sx = cx + rx * pScale;
          const sy = cy + ly * pScale;
          if (i === 0) ctx.moveTo(sx, sy);
          else ctx.lineTo(sx, sy);
        }
        ctx.strokeStyle = 'rgba(94, 224, 178, 0.07)';
        ctx.lineWidth = 1;
        ctx.stroke();
      }

      // central glow
      const pulse = 0.5 + 0.5 * Math.sin(now / 1100);
      const hubR = Math.min(W, H) * 0.22;
      const hubGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, hubR);
      hubGrad.addColorStop(0, `rgba(16, 182, 130, ${0.18 + 0.1 * pulse})`);
      hubGrad.addColorStop(0.5, 'rgba(14, 166, 120, 0.05)');
      hubGrad.addColorStop(1, 'rgba(14, 166, 120, 0)');
      ctx.fillStyle = hubGrad;
      ctx.beginPath();
      ctx.arc(cx, cy, hubR, 0, Math.PI * 2);
      ctx.fill();

      if (running) raf = requestAnimationFrame(draw);
    }

    const ro = new ResizeObserver(resize);
    ro.observe(canvas);
    resize();
    window.addEventListener('pointermove', onPointerMove, { passive: true });

    if (reduced) draw(performance.now());
    else raf = requestAnimationFrame(draw);

    const onVis = () => {
      if (document.hidden) {
        if (raf) cancelAnimationFrame(raf);
        raf = 0;
      } else if (running && !raf) {
        last = performance.now();
        raf = requestAnimationFrame(draw);
      }
    };
    document.addEventListener('visibilitychange', onVis);

    return () => {
      if (raf) cancelAnimationFrame(raf);
      ro.disconnect();
      window.removeEventListener('pointermove', onPointerMove);
      document.removeEventListener('visibilitychange', onVis);
    };
  }, []);

  return (
    <>
      <canvas ref={canvasRef} className="al-canvas" aria-hidden="true" />
      <div ref={knowledgeRef} className="al-knowledge-scene" aria-hidden="true">
        <span className="al-knowledge-item"><i className="bi bi-book-half" /></span>
        <span className="al-knowledge-item"><i className="bi bi-pencil" /></span>
        <span className="al-knowledge-item"><i className="bi bi-mortarboard" /></span>
        <span className="al-knowledge-item"><i className="bi bi-lightbulb" /></span>
        <span className="al-knowledge-item"><i className="bi bi-calculator" /></span>
        <span className="al-knowledge-item"><i className="bi bi-journal-bookmark" /></span>
        <span className="al-knowledge-item"><i className="bi bi-globe2" /></span>
        <span className="al-knowledge-item"><i className="bi bi-rulers" /></span>
      </div>
    </>
  );
}
