import { useRef, useEffect, useCallback } from 'react';
import { useThemeStore } from '../store/theme';

/**
 * Aurora background — 5 large diffuse orbs with additive blending.
 * V2: 接入 themeStore,浅色态用 pastel orb + 白色 vignette/gradient,深色保持原品牌色。
 */

interface Orb {
  cx: number;   // base center X ratio (0-1)
  cy: number;   // base center Y ratio (0-1)
  color: [number, number, number];
  alpha: number;
  phase: number;
  freqX: number;
  freqY: number;
  ampX: number;
  ampY: number;
  radius: number;
  breathFreq: number;
  breathAmp: number;
}

// Dark theme orbs — vivid 品牌色（青/紫/蓝）
const DARK_ORBS: Orb[] = [
  { cx: 0.25, cy: 0.30, color: [126, 220, 200], alpha: 0.28,
    phase: 0, freqX: 0.00012, freqY: 0.00010, ampX: 0.12, ampY: 0.10,
    radius: 0.50, breathFreq: 0.0004, breathAmp: 0.06 },
  { cx: 0.72, cy: 0.65, color: [108, 99, 255], alpha: 0.22,
    phase: 1.8, freqX: 0.00010, freqY: 0.00014, ampX: 0.14, ampY: 0.12,
    radius: 0.45, breathFreq: 0.0003, breathAmp: 0.08 },
  { cx: 0.58, cy: 0.38, color: [59, 130, 246], alpha: 0.18,
    phase: 3.2, freqX: 0.00015, freqY: 0.00008, ampX: 0.10, ampY: 0.15,
    radius: 0.38, breathFreq: 0.0005, breathAmp: 0.07 },
  { cx: 0.20, cy: 0.70, color: [167, 139, 250], alpha: 0.15,
    phase: 4.5, freqX: 0.00008, freqY: 0.00012, ampX: 0.16, ampY: 0.08,
    radius: 0.40, breathFreq: 0.00035, breathAmp: 0.10 },
  { cx: 0.78, cy: 0.25, color: [34, 211, 238], alpha: 0.20,
    phase: 5.8, freqX: 0.00014, freqY: 0.00016, ampX: 0.08, ampY: 0.12,
    radius: 0.35, breathFreq: 0.00045, breathAmp: 0.09 },
];

// Light theme orbs — pastel 浅色,alpha 减半左右,给玻璃面提供穿透色源
const LIGHT_ORBS: Orb[] = [
  { cx: 0.25, cy: 0.30, color: [180, 167, 255], alpha: 0.32,  // pastel lavender
    phase: 0, freqX: 0.00012, freqY: 0.00010, ampX: 0.12, ampY: 0.10,
    radius: 0.55, breathFreq: 0.0004, breathAmp: 0.06 },
  { cx: 0.72, cy: 0.65, color: [167, 200, 255], alpha: 0.28,  // pastel sky
    phase: 1.8, freqX: 0.00010, freqY: 0.00014, ampX: 0.14, ampY: 0.12,
    radius: 0.50, breathFreq: 0.0003, breathAmp: 0.08 },
  { cx: 0.58, cy: 0.38, color: [255, 180, 130, ], alpha: 0.18,  // pastel peach
    phase: 3.2, freqX: 0.00015, freqY: 0.00008, ampX: 0.10, ampY: 0.15,
    radius: 0.42, breathFreq: 0.0005, breathAmp: 0.07 },
  { cx: 0.20, cy: 0.70, color: [220, 167, 255], alpha: 0.20,  // pastel pink-violet
    phase: 4.5, freqX: 0.00008, freqY: 0.00012, ampX: 0.16, ampY: 0.08,
    radius: 0.45, breathFreq: 0.00035, breathAmp: 0.10 },
  { cx: 0.78, cy: 0.25, color: [180, 220, 255], alpha: 0.22,  // pastel blue
    phase: 5.8, freqX: 0.00014, freqY: 0.00016, ampX: 0.08, ampY: 0.12,
    radius: 0.40, breathFreq: 0.00045, breathAmp: 0.09 },
];

const MOUSE_RADIUS = 400;
const MOUSE_PUSH = 28;

export function AuroraCanvas() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const grainRef = useRef<HTMLCanvasElement>(null);
  const mouseRef = useRef({ x: -9999, y: -9999, active: false });
  const theme = useThemeStore((s) => s.theme);
  const isLight = theme === 'light';

  const handleMouseMove = useCallback((e: MouseEvent) => {
    mouseRef.current.x = e.clientX;
    mouseRef.current.y = e.clientY;
    mouseRef.current.active = true;
  }, []);

  const handleMouseLeave = useCallback(() => {
    mouseRef.current.active = false;
  }, []);

  // ── Aurora animation ──
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    let w = window.innerWidth;
    let h = window.innerHeight;

    function resize() {
      w = window.innerWidth;
      h = window.innerHeight;
      const dpr = w < 768 ? 0.5 : Math.min(window.devicePixelRatio, 1.5);
      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);
    }

    resize();

    let animId: number;
    const t0 = performance.now();
    let smoothMx = -9999;
    let smoothMy = -9999;

    const orbs = isLight ? LIGHT_ORBS : DARK_ORBS;

    function draw(now: number) {
      const t = now - t0;
      ctx!.clearRect(0, 0, w, h);
      // 浅色用 source-over 让 pastel 互融时不会过曝;深色继续用 lighter 加合
      ctx!.globalCompositeOperation = isLight ? 'source-over' : 'lighter';

      const mouse = mouseRef.current;
      if (mouse.active) {
        smoothMx += (mouse.x - smoothMx) * 0.035;
        smoothMy += (mouse.y - smoothMy) * 0.035;
      } else {
        smoothMx += (-9999 - smoothMx) * 0.01;
        smoothMy += (-9999 - smoothMy) * 0.01;
      }

      for (const orb of orbs) {
        let x = w * (orb.cx + Math.sin(t * orb.freqX + orb.phase) * orb.ampX);
        let y = h * (orb.cy + Math.cos(t * orb.freqY + orb.phase * 0.7) * orb.ampY);

        const dx = x - smoothMx;
        const dy = y - smoothMy;
        const dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < MOUSE_RADIUS && dist > 1) {
          const strength = (1 - dist / MOUSE_RADIUS) * MOUSE_PUSH;
          x += (dx / dist) * strength;
          y += (dy / dist) * strength;
        }

        const breathT = Math.sin(t * orb.breathFreq + orb.phase * 1.3);
        const r = Math.max(w, h) * orb.radius * (1 + breathT * orb.breathAmp);
        const a = orb.alpha * (1 + breathT * 0.15);

        const [cr, cg, cb] = orb.color;
        const grad = ctx!.createRadialGradient(x, y, 0, x, y, r);
        grad.addColorStop(0,   `rgba(${cr},${cg},${cb},${(a).toFixed(3)})`);
        grad.addColorStop(0.25, `rgba(${cr},${cg},${cb},${(a * 0.5).toFixed(3)})`);
        grad.addColorStop(0.5, `rgba(${cr},${cg},${cb},${(a * 0.15).toFixed(3)})`);
        grad.addColorStop(0.8, `rgba(${cr},${cg},${cb},${(a * 0.03).toFixed(3)})`);
        grad.addColorStop(1,   `rgba(${cr},${cg},${cb},0)`);

        ctx!.fillStyle = grad;
        ctx!.beginPath();
        ctx!.arc(x, y, r, 0, Math.PI * 2);
        ctx!.fill();
      }

      ctx!.globalCompositeOperation = 'source-over';
      animId = requestAnimationFrame(draw);
    }

    animId = requestAnimationFrame(draw);
    window.addEventListener('resize', resize);
    window.addEventListener('mousemove', handleMouseMove, { passive: true });
    document.addEventListener('mouseleave', handleMouseLeave);

    return () => {
      cancelAnimationFrame(animId);
      window.removeEventListener('resize', resize);
      window.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseleave', handleMouseLeave);
    };
  }, [handleMouseMove, handleMouseLeave, isLight]);

  // ── Film grain — 4 FPS low-noise ──
  useEffect(() => {
    const canvas = grainRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    canvas.width = 256;
    canvas.height = 256;

    let animId: number;
    let lastFrame = 0;

    function drawGrain(now: number) {
      if (now - lastFrame > 250) {
        lastFrame = now;
        const img = ctx!.createImageData(256, 256);
        const d = img.data;
        for (let i = 0; i < d.length; i += 4) {
          const v = Math.random() * 255;
          d[i] = d[i + 1] = d[i + 2] = v;
          d[i + 3] = 255;
        }
        ctx!.putImageData(img, 0, 0);
      }
      animId = requestAnimationFrame(drawGrain);
    }

    animId = requestAnimationFrame(drawGrain);
    return () => cancelAnimationFrame(animId);
  }, []);

  // 浅色态:vignette / gradient 反相 — 用白色压边,黑色压边在浅色上是错的
  const vignetteColor = isLight ? 'rgba(255,255,255,0.6)' : 'rgba(0,0,0,0.8)';
  const fadeColor = isLight ? 'rgba(250,250,250,0.7)' : 'rgba(0,0,0,0.5)';

  return (
    <>
      {/* Layer 1: Vignette — radial fading, 浅色下用白色 */}
      <div
        style={{
          position: 'absolute',
          inset: 0,
          zIndex: 1,
          background: `radial-gradient(ellipse 65% 55% at 50% 50%, transparent 0%, ${vignetteColor} 100%)`,
          pointerEvents: 'none',
        }}
      />

      {/* Layer 2: Film grain — 浅色下大幅减弱避免噪点过曝 */}
      <canvas
        ref={grainRef}
        style={{
          position: 'absolute',
          inset: 0,
          zIndex: 2,
          width: '100%',
          height: '100%',
          opacity: isLight ? 0.015 : 0.035,
          pointerEvents: 'none',
          mixBlendMode: isLight ? 'multiply' : 'overlay',
        }}
      />

      {/* Layer 3: Aurora — blur 让 orb 融成有机晕染 */}
      <canvas
        ref={canvasRef}
        style={{
          position: 'absolute',
          inset: 0,
          zIndex: 3,
          filter: 'blur(50px)',
          pointerEvents: 'none',
        }}
      />

      {/* Layer 4: 顶/底渐变压角 */}
      <div
        style={{
          position: 'absolute',
          inset: 0,
          zIndex: 4,
          pointerEvents: 'none',
          background:
            `linear-gradient(to bottom, ${fadeColor} 0%, transparent 18%, transparent 82%, ${fadeColor} 100%)`,
        }}
      />
    </>
  );
}
