"use client";
// 回响星核 / Echo Nexus — 星图天文台面板（飞升元进程可视化）
// 6 个星座（六边形布局）× 3 颗星 = 18 个天赋节点，已解锁的星点亮 + 连线
import { useEffect, useRef, useState, useMemo } from "react";
import { useGameStore } from "@/store/gameStore";
import {
  CONSTELLATION_PERKS,
  CONSTELLATION_CATEGORY_META,
  getPerk,
  constellationBonuses,
  getConstellationLayout,
  getStarsInCategory,
  countUnlockedInCategory,
  constellationProgress,
  type ConstellationCategory,
} from "@/lib/game/constellation";
import type { ConstellationPerk } from "@/lib/game/constellation";

interface StarPoint {
  perk: ConstellationPerk;
  x: number;
  y: number;
}

interface HoverState {
  perk: ConstellationPerk;
  x: number;
  y: number;
  unlocked: boolean;
}

export function ConstellationPanel() {
  const constellation = useGameStore((s) => s.constellation ?? []);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const containerRef = useRef<HTMLDivElement | null>(null);
  const [size, setSize] = useState({ w: 360, h: 360 });
  const [hover, setHover] = useState<HoverState | null>(null);
  const ownedSet = useMemo(() => new Set(constellation), [constellation]);

  // 自适应尺寸
  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const ro = new ResizeObserver(() => {
      const r = el.getBoundingClientRect();
      setSize({ w: Math.max(280, r.width), h: Math.max(280, Math.min(420, r.width)) });
    });
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  // 计算布局（中心点 + 半径）
  const layout = useMemo(() => {
    const cx = size.w / 2;
    const cy = size.h / 2;
    const radius = Math.min(size.w, size.h) * 0.32;
    return { cx, cy, radius };
  }, [size]);

  // 收集所有星点 + 每个星座的星点列表
  const clusters = useMemo(() => {
    const centers = getConstellationLayout(layout.cx, layout.cy, layout.radius);
    return centers.map((c) => {
      const stars = getStarsInCategory(c.category, c.cx, c.cy, 1) as StarPoint[];
      return { ...c, stars };
    });
  }, [layout]);

  // 绘制
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;
    const dpr = window.devicePixelRatio || 1;
    canvas.width = size.w * dpr;
    canvas.height = size.h * dpr;
    canvas.style.width = `${size.w}px`;
    canvas.style.height = `${size.h}px`;
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    let rafId = 0;
    const start = performance.now();
    const draw = (now: number) => {
      const t = (now - start) / 1000;
      ctx.clearRect(0, 0, size.w, size.h);
      // 背景径向暗光
      const bg = ctx.createRadialGradient(layout.cx, layout.cy, 0, layout.cx, layout.cy, layout.radius * 1.6);
      bg.addColorStop(0, "rgba(40,30,80,0.18)");
      bg.addColorStop(1, "rgba(5,4,16,0)");
      ctx.fillStyle = bg;
      ctx.fillRect(0, 0, size.w, size.h);

      // 中心装饰：星核
      ctx.save();
      ctx.translate(layout.cx, layout.cy);
      const coreR = 6 + Math.sin(t * 1.5) * 1.5;
      const coreGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, coreR * 3);
      coreGrad.addColorStop(0, "rgba(232,121,249,0.9)");
      coreGrad.addColorStop(0.4, "rgba(232,121,249,0.3)");
      coreGrad.addColorStop(1, "rgba(232,121,249,0)");
      ctx.fillStyle = coreGrad;
      ctx.beginPath();
      ctx.arc(0, 0, coreR * 3, 0, Math.PI * 2);
      ctx.fill();
      ctx.fillStyle = "#fce7ff";
      ctx.beginPath();
      ctx.arc(0, 0, coreR * 0.6, 0, Math.PI * 2);
      ctx.fill();
      ctx.restore();

      // 连接星座到中心的虚线（已解锁 >=1 时）
      for (const c of clusters) {
        const cnt = countUnlockedInCategory(constellation, c.category);
        if (cnt > 0) {
          ctx.save();
          ctx.strokeStyle = c.meta.glow;
          ctx.lineWidth = 1;
          ctx.setLineDash([2, 4]);
          ctx.globalAlpha = 0.4 + Math.sin(t * 2 + c.cx) * 0.1;
          ctx.beginPath();
          ctx.moveTo(layout.cx, layout.cy);
          ctx.lineTo(c.cx, c.cy);
          ctx.stroke();
          ctx.restore();
        }
      }

      // 绘制每个星座
      for (const c of clusters) {
        const cnt = countUnlockedInCategory(constellation, c.category);
        // 星座中心标签
        ctx.save();
        ctx.font = "10px ui-monospace, monospace";
        ctx.textAlign = "center";
        ctx.fillStyle = cnt > 0 ? c.meta.hex : "rgba(148,163,184,0.5)";
        ctx.globalAlpha = 0.85;
        ctx.fillText(c.meta.name, c.cx, c.cy + 38);
        ctx.restore();

        // 同星座内已解锁星点之间的连线
        const unlockedStars = c.stars.filter((s) => ownedSet.has(s.perk.id));
        if (unlockedStars.length >= 2) {
          ctx.save();
          ctx.strokeStyle = c.meta.glow;
          ctx.lineWidth = 1.5;
          ctx.globalAlpha = 0.6;
          ctx.beginPath();
          unlockedStars.forEach((s, i) => {
            if (i === 0) ctx.moveTo(s.x, s.y);
            else ctx.lineTo(s.x, s.y);
          });
          ctx.stroke();
          ctx.restore();
        }

        // 绘制星点
        for (const star of c.stars) {
          const unlocked = ownedSet.has(star.perk.id);
          ctx.save();
          ctx.translate(star.x, star.y);
          // 闪烁系数
          const twinkle = unlocked ? 0.85 + Math.sin(t * 3 + star.x * 0.1) * 0.15 : 0.3;
          // 外光晕
          const haloR = unlocked ? 10 : 5;
          const haloGrad = ctx.createRadialGradient(0, 0, 0, 0, 0, haloR);
          haloGrad.addColorStop(0, unlocked ? c.meta.glow : "rgba(100,116,139,0.2)");
          haloGrad.addColorStop(1, "rgba(0,0,0,0)");
          ctx.fillStyle = haloGrad;
          ctx.globalAlpha = twinkle;
          ctx.beginPath();
          ctx.arc(0, 0, haloR, 0, Math.PI * 2);
          ctx.fill();
          // 核心
          ctx.globalAlpha = unlocked ? 1 : 0.4;
          ctx.fillStyle = unlocked ? c.meta.hex : "#475569";
          ctx.beginPath();
          ctx.arc(0, 0, unlocked ? 3.5 : 2, 0, Math.PI * 2);
          ctx.fill();
          // 解锁星点：4 道十字光线
          if (unlocked) {
            ctx.strokeStyle = c.meta.hex;
            ctx.globalAlpha = 0.7 * twinkle;
            ctx.lineWidth = 0.8;
            const ray = 7 + Math.sin(t * 4 + star.y * 0.1) * 1.5;
            ctx.beginPath();
            ctx.moveTo(-ray, 0); ctx.lineTo(ray, 0);
            ctx.moveTo(0, -ray); ctx.lineTo(0, ray);
            ctx.stroke();
          }
          ctx.restore();
        }
      }

      rafId = requestAnimationFrame(draw);
    };
    rafId = requestAnimationFrame(draw);
    return () => cancelAnimationFrame(rafId);
  }, [clusters, layout, size, constellation, ownedSet]);

  // 鼠标交互：检测 hover
  const handleMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const rect = canvas.getBoundingClientRect();
    const mx = e.clientX - rect.left;
    const my = e.clientY - rect.top;
    let best: HoverState | null = null;
    let bestDist = 14;
    for (const c of clusters) {
      for (const star of c.stars) {
        const d = Math.hypot(star.x - mx, star.y - my);
        if (d < bestDist) {
          bestDist = d;
          best = {
            perk: star.perk,
            x: star.x,
            y: star.y,
            unlocked: ownedSet.has(star.perk.id),
          };
        }
      }
    }
    setHover(best);
  };
  const handleLeave = () => setHover(null);

  const progress = constellationProgress(constellation);

  return (
    <div ref={containerRef} className="flex flex-col gap-2 min-h-0 h-full">
      {/* 顶部进度 */}
      <div className="flex items-center justify-between text-[11px] px-1">
        <div className="flex items-center gap-1.5">
          <span className="text-fuchsia-300">✦</span>
          <span className="text-muted-foreground">星图天赋</span>
          <span className="font-mono text-foreground">
            {progress.unlocked}/{progress.total}
          </span>
        </div>
        <span className="text-muted-foreground/60 text-[10px]">每次飞升可解锁 1 个</span>
      </div>

      {/* Canvas 星图 */}
      <div className="relative rounded-xl bg-black/30 border border-white/5 overflow-hidden flex-shrink-0">
        <canvas
          ref={canvasRef}
          onMouseMove={handleMove}
          onMouseLeave={handleLeave}
          className="block cursor-pointer"
        />
        {/* Hover tooltip */}
        {hover && (
          <div
            className="pointer-events-none absolute z-10 max-w-[200px] rounded-md bg-black/85 border border-white/10 px-2 py-1.5 text-[10px] leading-tight shadow-lg backdrop-blur-sm"
            style={{
              left: Math.min(hover.x + 12, size.w - 200),
              top: Math.max(0, hover.y - 40),
            }}
          >
            <div
              className="font-bold mb-0.5"
              style={{ color: CONSTELLATION_CATEGORY_META[hover.perk.category].hex }}
            >
              {hover.unlocked ? "★ " : "☆ "}
              {hover.perk.name}
            </div>
            <div className="text-muted-foreground">{hover.perk.desc}</div>
            <div className="text-muted-foreground/60 mt-0.5">
              {CONSTELLATION_CATEGORY_META[hover.perk.category].name} · 序{hover.perk.order}
            </div>
          </div>
        )}
      </div>

      {/* 类别图例 + 当前总修饰 */}
      <div className="grid grid-cols-3 gap-1 text-[10px]">
        {(Object.keys(CONSTELLATION_CATEGORY_META) as ConstellationCategory[]).map((cat) => {
          const meta = CONSTELLATION_CATEGORY_META[cat];
          const cnt = countUnlockedInCategory(constellation, cat);
          const total = CONSTELLATION_PERKS.filter((p) => p.category === cat).length;
          return (
            <div
              key={cat}
              className="rounded-md bg-black/25 border border-white/5 px-1.5 py-1 flex items-center gap-1"
              style={cnt > 0 ? { borderColor: `${meta.hex}40` } : undefined}
            >
              <span
                className="inline-block h-1.5 w-1.5 rounded-full flex-shrink-0"
                style={{ background: meta.hex, boxShadow: cnt > 0 ? `0 0 4px ${meta.hex}` : "none" }}
              />
              <span className="text-muted-foreground truncate">{meta.name}</span>
              <span className="ml-auto font-mono" style={{ color: cnt > 0 ? meta.hex : "rgba(148,163,184,0.5)" }}>
                {cnt}/{total}
              </span>
            </div>
          );
        })}
      </div>

      {/* 已解锁天赋列表 */}
      <div className="flex-1 min-h-0 overflow-y-auto pr-1 echo-scrollbar">
        {constellation.length === 0 ? (
          <div className="rounded-md bg-black/25 border border-dashed border-white/10 px-3 py-3 text-center text-[11px] text-muted-foreground/70">
            <div className="mb-1 text-fuchsia-300/80">✦</div>
            尚未解锁任何天赋。<br />
            累积接触进度至 100%，发起「飞升」即可在 3 个随机天赋中选 1。
          </div>
        ) : (
          <div className="flex flex-col gap-1">
            {constellation.map((id) => {
              const perk = getPerk(id);
              if (!perk) return null;
              const meta = CONSTELLATION_CATEGORY_META[perk.category];
              return (
                <div
                  key={id}
                  className="rounded-md bg-black/25 border px-2 py-1.5 flex items-center gap-2 text-[11px]"
                  style={{ borderColor: `${meta.hex}30` }}
                >
                  <span
                    className="inline-block h-2 w-2 rounded-full flex-shrink-0"
                    style={{ background: meta.hex, boxShadow: `0 0 6px ${meta.hex}` }}
                  />
                  <div className="flex-1 min-w-0">
                    <div className="text-foreground truncate">{perk.name}</div>
                    <div className="text-muted-foreground/70 text-[10px] truncate">{perk.desc}</div>
                  </div>
                  <span className="text-[9px] text-muted-foreground/50 font-mono">{meta.name}</span>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
}
