"use client";
// 回响星核 / Echo Nexus — 深空星空背景 Canvas
import { useEffect, useRef } from "react";

interface Star {
  x: number;
  y: number;
  z: number; // 深度 0-1
  r: number;
  tw: number; // 闪烁相位
  hue: number;
}

interface Dust {
  x: number;
  y: number;
  vx: number;
  vy: number;
  life: number;
  maxLife: number;
  color: string;
}

export function StarfieldCanvas({ className }: { className?: string }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    let w = 0;
    let h = 0;
    let dpr = 1;
    let stars: Star[] = [];
    const dust: Dust[] = [];
    let raf = 0;
    let lastT = performance.now();

    const palette = ["#34d399", "#fb7185", "#fbbf24", "#e879f9", "#a5f3fc"];

    function resize() {
      dpr = Math.min(2, window.devicePixelRatio || 1);
      w = canvas!.clientWidth;
      h = canvas!.clientHeight;
      canvas!.width = Math.floor(w * dpr);
      canvas!.height = Math.floor(h * dpr);
      ctx!.setTransform(dpr, 0, 0, dpr, 0, 0);
      // 生成星星：密度随面积
      const count = Math.min(220, Math.floor((w * h) / 7000));
      stars = Array.from({ length: count }, () => ({
        x: Math.random() * w,
        y: Math.random() * h,
        z: Math.random(),
        r: Math.random() * 1.4 + 0.2,
        tw: Math.random() * Math.PI * 2,
        hue: Math.random() < 0.15 ? Math.floor(Math.random() * palette.length) : -1,
      }));
    }
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(canvas);

    function spawnDust() {
      if (dust.length > 60) return;
      const color = palette[Math.floor(Math.random() * palette.length)];
      dust.push({
        x: Math.random() * w,
        y: h + 10,
        vx: (Math.random() - 0.5) * 0.3,
        vy: -(Math.random() * 0.5 + 0.2),
        life: 0,
        maxLife: 600 + Math.random() * 800,
        color,
      });
    }

    function draw(t: number) {
      const dt = t - lastT;
      lastT = t;
      // 背景渐变
      const g = ctx!.createRadialGradient(w * 0.5, h * 0.4, 0, w * 0.5, h * 0.5, Math.max(w, h) * 0.8);
      g.addColorStop(0, "#1a0f2e");
      g.addColorStop(0.45, "#0d0a1f");
      g.addColorStop(1, "#050410");
      ctx!.fillStyle = g;
      ctx!.fillRect(0, 0, w, h);

      // 星云团块
      ctx!.globalCompositeOperation = "screen";
      for (let i = 0; i < 3; i++) {
        const cx = w * (0.2 + i * 0.3) + Math.sin(t / 9000 + i) * 40;
        const cy = h * (0.3 + (i % 2) * 0.4) + Math.cos(t / 11000 + i) * 30;
        const rad = Math.max(80, Math.min(w, h) * (0.25 + i * 0.05));
        const ng = ctx!.createRadialGradient(cx, cy, 0, cx, cy, rad);
        const col = i === 0 ? "rgba(232,121,249,0.10)" : i === 1 ? "rgba(52,211,153,0.08)" : "rgba(251,113,133,0.08)";
        ng.addColorStop(0, col);
        ng.addColorStop(1, "rgba(0,0,0,0)");
        ctx!.fillStyle = ng;
        ctx!.beginPath();
        ctx!.arc(cx, cy, rad, 0, Math.PI * 2);
        ctx!.fill();
      }
      ctx!.globalCompositeOperation = "source-over";

      // 星星
      for (const s of stars) {
        s.tw += 0.02 + s.z * 0.04;
        const alpha = 0.4 + Math.sin(s.tw) * 0.35 + s.z * 0.3;
        if (s.hue >= 0) {
          ctx!.fillStyle = palette[s.hue];
          ctx!.globalAlpha = Math.max(0, Math.min(1, alpha));
          ctx!.beginPath();
          ctx!.arc(s.x, s.y, s.r * 1.6, 0, Math.PI * 2);
          ctx!.fill();
          // 光晕
          ctx!.globalAlpha = Math.max(0, Math.min(1, alpha * 0.25));
          ctx!.beginPath();
          ctx!.arc(s.x, s.y, s.r * 4, 0, Math.PI * 2);
          ctx!.fill();
        } else {
          ctx!.fillStyle = `rgba(220,230,255,${Math.max(0, Math.min(1, alpha))})`;
          ctx!.beginPath();
          ctx!.arc(s.x, s.y, s.r, 0, Math.PI * 2);
          ctx!.fill();
        }
        // 缓慢漂移
        s.y += 0.02 + s.z * 0.05;
        if (s.y > h + 2) {
          s.y = -2;
          s.x = Math.random() * w;
        }
      }
      ctx!.globalAlpha = 1;

      // 偶尔生成星尘
      if (Math.random() < 0.04) spawnDust();
      // 星尘
      ctx!.globalCompositeOperation = "screen";
      for (let i = dust.length - 1; i >= 0; i--) {
        const d = dust[i];
        d.life += dt;
        d.x += d.vx * dt * 0.06;
        d.y += d.vy * dt * 0.06;
        if (d.life > d.maxLife || d.y < -10) {
          dust.splice(i, 1);
          continue;
        }
        const a = Math.sin((d.life / d.maxLife) * Math.PI) * 0.7;
        ctx!.fillStyle = d.color;
        ctx!.globalAlpha = a;
        ctx!.beginPath();
        ctx!.arc(d.x, d.y, 1.6, 0, Math.PI * 2);
        ctx!.fill();
        ctx!.globalAlpha = a * 0.2;
        ctx!.beginPath();
        ctx!.arc(d.x, d.y, 5, 0, Math.PI * 2);
        ctx!.fill();
      }
      ctx!.globalAlpha = 1;
      ctx!.globalCompositeOperation = "source-over";

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

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      className={className}
      aria-hidden="true"
    />
  );
}
