"use client";
// 回响星核 / Echo Nexus — 解码共振谜题（核心原创玩法）
//
// 谐振序列：按目标颜色顺序点击四邻接节点，重建回路。
import { useState } from "react";
import { useGameStore } from "@/store/gameStore";
import { useToast } from "@/hooks/use-toast";
import { sfx } from "@/hooks/useAudio";
import { COLOR_VISUAL } from "@/lib/game/config";
import { isSolvable, canStartFrom } from "@/lib/game/decode";
import type { DecodeNode, ResonanceColor } from "@/lib/game/types";
import { Button } from "@/components/ui/button";
import { RotateCcw, X, Sparkles, Check, Undo2, AlertTriangle } from "lucide-react";

export function DecodeArray() {
  const activePuzzle = useGameStore((s) => s.activePuzzle);
  const clickNode = useGameStore((s) => s.clickNode);
  const undoStep = useGameStore((s) => s.undoStep);
  const retryPuzzle = useGameStore((s) => s.retryPuzzle);
  const abandonPuzzle = useGameStore((s) => s.abandonPuzzle);
  const { toast } = useToast();

  const [hoverId, setHoverId] = useState<number | null>(null);
  const [flash, setFlash] = useState<{ id: number; ok: boolean } | null>(null);
  const [warned, setWarned] = useState(false);

  if (!activePuzzle) return null;

  const { grid, rows, cols, target, path, stepLimit, tier } = activePuzzle;
  const currentTargetIdx = path.length;
  const currentColor: ResonanceColor | undefined = target[currentTargetIdx];
  // 当前局面是否仍可解（精确判定）
  const stuck = path.length > 0 && path.length < target.length && !isSolvable(activePuzzle);

  const handleNodeClick = (node: DecodeNode) => {
    const res = clickNode(node.id);
    if (res.ok && res.finished) {
      setWarned(false);
      sfx("decodeSuccess");
      if (res.failReason) {
        const ids = res.failReason.split(",").filter(Boolean);
        if (ids.length) {
          sfx("fragmentUnlock");
          toast({
            title: "✦ 记忆碎片浮现",
            description: "新的回响被拼入图谱，前往「记忆图谱」查看。",
          });
        }
      }
      toast({
        title: "谐振闭合！",
        description: "晶体解码成功，记忆已释放。",
      });
      return;
    }
    if (!res.ok) {
      sfx("decodeFail");
      setFlash({ id: node.id, ok: false });
      setTimeout(() => setFlash(null), 280);
    } else {
      sfx("decodeClick", { color: node.color });
      setFlash({ id: node.id, ok: true });
      setTimeout(() => setFlash(null), 280);
      // 点击后若不可解，提示玩家撤销
      if (res.solvable === false && !warned) {
        setWarned(true);
        toast({
          title: "谐振受阻",
          description: "此路不通，建议撤销上一步或重排。",
        });
      }
      if (res.solvable === true) setWarned(false);
    }
  };

  const handleUndo = () => {
    undoStep();
    setWarned(false);
    setFlash(null);
  };

  const handleRetry = () => {
    retryPuzzle();
    setWarned(false);
    setFlash(null);
  };

  // 计算节点位置（百分比）
  const cellW = 100 / cols;
  const cellH = 100 / rows;

  // 路径线段
  const pathNodes = path
    .map((id) => grid.find((n) => n.id === id)!)
    .filter(Boolean);

  return (
    <div className="flex flex-col gap-4 h-full">
      {/* 目标序列 */}
      <div className="flex items-center justify-center gap-2 flex-wrap">
        <span className="text-xs text-muted-foreground mr-1">目标谐振</span>
        {target.map((c, i) => {
          const done = i < currentTargetIdx;
          const active = i === currentTargetIdx;
          const v = COLOR_VISUAL[c];
          return (
            <div
              key={i}
              className={`relative h-9 w-9 rounded-full flex items-center justify-center transition-all duration-300 ${
                done ? "opacity-30 scale-90" : ""
              } ${active ? "scale-125 ring-2 ring-offset-2 ring-offset-background" : ""}`}
              style={{
                background: `radial-gradient(circle at 35% 30%, ${v.hex}, ${v.hex}aa 60%, ${v.hex}44)`,
                boxShadow: active
                  ? `0 0 18px ${v.glow}, 0 0 36px ${v.glow}`
                  : `0 0 8px ${v.glow}`,
                ["--tw-ring-color" as string]: v.hex,
              }}
            >
              {done && <Check className="h-4 w-4 text-white" />}
              {active && (
                <span
                  className="absolute -bottom-5 text-[10px] font-medium"
                  style={{ color: v.hex }}
                >
                  下一个
                </span>
              )}
            </div>
          );
        })}
      </div>

      {/* 节点阵列 */}
      <div className="relative flex-1 min-h-[260px] rounded-2xl border border-white/10 bg-black/30 backdrop-blur-sm overflow-hidden">
        {/* 背景网格线 */}
        <div
          className="absolute inset-0 opacity-20"
          style={{
            backgroundImage:
              "linear-gradient(rgba(255,255,255,0.08) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.08) 1px, transparent 1px)",
            backgroundSize: `${cellW}% ${cellH}%`,
          }}
        />
        {/* 路径线 SVG */}
        <svg className="absolute inset-0 w-full h-full pointer-events-none">
          {pathNodes.map((n, i) => {
            if (i === 0) return null;
            const prev = pathNodes[i - 1];
            const x1 = (prev.col + 0.5) * cellW;
            const y1 = (prev.row + 0.5) * cellH;
            const x2 = (n.col + 0.5) * cellW;
            const y2 = (n.row + 0.5) * cellH;
            const v = COLOR_VISUAL[n.color];
            return (
              <line
                key={i}
                x1={`${x1}%`}
                y1={`${y1}%`}
                x2={`${x2}%`}
                y2={`${y2}%`}
                stroke={v.hex}
                strokeWidth={2.5}
                strokeLinecap="round"
                style={{ filter: `drop-shadow(0 0 4px ${v.glow})` }}
                className="echo-path-line"
              />
            );
          })}
        </svg>

        {/* 节点 */}
        {grid.map((node) => {
          const v = COLOR_VISUAL[node.color];
          const used = node.used;
          const isCurrentTarget =
            currentColor !== undefined && node.color === currentColor && !used;
          // 选起点阶段：标记「可行起点」（选了之后仍可解），避免玩家踩死起点
          const isViableStart =
            path.length === 0 && isCurrentTarget && canStartFrom(activePuzzle, node.id);
          // 选起点阶段：是目标色但选了会死局的起点（淡化提示）
          const isDeadStart =
            path.length === 0 && isCurrentTarget && !isViableStart;
          const isHover = hoverId === node.id;
          const isFlash = flash?.id === node.id;
          const cx = (node.col + 0.5) * cellW;
          const cy = (node.row + 0.5) * cellH;
          return (
            <button
              key={node.id}
              onClick={() => handleNodeClick(node)}
              onMouseEnter={() => setHoverId(node.id)}
              onMouseLeave={() => setHoverId(null)}
              disabled={used}
              className="absolute -translate-x-1/2 -translate-y-1/2 rounded-full transition-all duration-200 focus:outline-none disabled:cursor-not-allowed"
              style={{
                left: `${cx}%`,
                top: `${cy}%`,
                width: `min(${100 / cols * 0.62}%, 56px)`,
                aspectRatio: "1",
                background: used
                  ? "rgba(255,255,255,0.04)"
                  : `radial-gradient(circle at 35% 30%, ${v.hex}, ${v.hex}cc 55%, ${v.hex}55)`,
                boxShadow: used
                  ? "inset 0 0 12px rgba(0,0,0,0.5)"
                  : isViableStart
                  ? `0 0 16px ${v.glow}, 0 0 32px ${v.glow}, inset 0 0 10px rgba(255,255,255,0.5)`
                  : isCurrentTarget
                  ? `0 0 10px ${v.glow}, 0 0 20px ${v.glow}, inset 0 0 6px rgba(255,255,255,0.3)`
                  : `0 0 6px ${v.glow}`,
                border: isViableStart
                  ? `2px solid ${v.hex}`
                  : isCurrentTarget
                  ? `1.5px solid ${v.hex}aa`
                  : "1px solid rgba(255,255,255,0.12)",
                opacity: used ? 0.35 : isDeadStart ? 0.5 : 1,
                transform: `translate(-50%, -50%) scale(${
                  isHover && !used ? 1.12 : isFlash ? (flash?.ok ? 1.25 : 0.8) : 1
                })`,
                animation: isViableStart
                  ? "echo-pulse 1.2s ease-in-out infinite"
                  : isCurrentTarget && !isDeadStart
                  ? "echo-pulse 1.6s ease-in-out infinite"
                  : undefined,
              }}
              aria-label={`${v.label}色节点 ${node.row + 1}-${node.col + 1}`}
            >
              {!used && (
                <span
                  className="absolute inset-0 rounded-full"
                  style={{
                    background:
                      "radial-gradient(circle at 35% 30%, rgba(255,255,255,0.5), transparent 45%)",
                  }}
                />
              )}
            </button>
          );
        })}
      </div>

      {/* 卡死提示横幅 */}
      {stuck && (
        <div className="flex items-center gap-2 px-3 py-2 rounded-lg border border-rose-400/40 bg-rose-950/40 text-rose-200 text-xs animate-pulse">
          <AlertTriangle className="h-3.5 w-3.5 shrink-0" />
          <span>谐振受阻，此路已无解。</span>
          <Button
            size="sm"
            variant="outline"
            onClick={handleUndo}
            className="h-6 px-2 ml-auto border-rose-400/50 text-rose-100 hover:bg-rose-500/20 text-[11px]"
          >
            <Undo2 className="h-3 w-3 mr-1" />
            撤销
          </Button>
        </div>
      )}

      {/* 底栏：步数 + 操作 */}
      <div className="flex items-center justify-between gap-3">
        <div className="flex items-center gap-2 text-xs">
          <span className="text-muted-foreground">步数</span>
          <span
            className={`font-mono font-semibold ${
              path.length >= stepLimit ? "text-rose-400" : "text-foreground"
            }`}
          >
            {path.length} / {stepLimit}
          </span>
          <span className="ml-2 text-muted-foreground">T{tier}</span>
        </div>
        <div className="flex items-center gap-1.5">
          <Button
            variant="ghost"
            size="sm"
            onClick={handleUndo}
            disabled={path.length === 0}
            className="h-7"
          >
            <Undo2 className="h-3.5 w-3.5 mr-1" />
            撤销
          </Button>
          <Button
            variant="ghost"
            size="sm"
            onClick={handleRetry}
            className="h-7"
          >
            <RotateCcw className="h-3.5 w-3.5 mr-1" />
            重排
          </Button>
          <Button
            variant="ghost"
            size="sm"
            onClick={() => {
              abandonPuzzle();
              setFlash(null);
              setWarned(false);
            }}
            className="h-7"
          >
            <X className="h-3.5 w-3.5 mr-1" />
            放回
          </Button>
        </div>
      </div>

      {/* 规则提示 */}
      <p className="text-[11px] text-muted-foreground/80 text-center leading-relaxed">
        {path.length === 0
          ? <>点击<span className="text-emerald-300">高亮</span>的可行起点开始，按目标顺序走<span className="text-emerald-300">相邻同色</span>节点；走错可<span className="text-rose-300">撤销</span>。</>
          : <>按「目标谐振」顺序，点击<span className="text-emerald-300">上下左右相邻</span>的同色节点。每个节点仅可使用一次；走错可<span className="text-rose-300">撤销</span>。</>}
      </p>

      <style jsx global>{`
        @keyframes echo-pulse {
          0%, 100% { filter: brightness(1); }
          50% { filter: brightness(1.4); }
        }
        @keyframes echo-line {
          from { stroke-dashoffset: 100; }
          to { stroke-dashoffset: 0; }
        }
        .echo-path-line {
          stroke-dasharray: 100;
          animation: echo-line 0.4s ease-out forwards;
        }
      `}</style>
    </div>
  );
}

/** 解码面板的容器（带标题） */
export function DecodePanel() {
  const activePuzzle = useGameStore((s) => s.activePuzzle);
  const pendingCrystals = useGameStore((s) => s.pendingCrystals);
  const startDecode = useGameStore((s) => s.startDecode);
  const crystalsPerSec = useGameStore((s) => s.crystalsPerSec);
  const crystalCap = useGameStore((s) => s.crystalCap);
  const crystals = useGameStore((s) => s.crystals);

  if (activePuzzle) {
    return (
      <div className="h-full flex flex-col">
        <div className="flex items-center gap-2 mb-3">
          <Sparkles className="h-4 w-4 text-rose-400" />
          <h3 className="text-sm font-semibold">解码共振阵列</h3>
        </div>
        <div className="flex-1 min-h-0">
          <DecodeArray />
        </div>
      </div>
    );
  }

  // 无活跃谜题：展示待解码晶体队列
  return (
    <div className="h-full flex flex-col">
      <div className="flex items-center gap-2 mb-3">
        <Sparkles className="h-4 w-4 text-rose-400" />
        <h3 className="text-sm font-semibold">待解码晶体</h3>
        <span className="text-xs text-muted-foreground ml-auto">
          产能 {crystalsPerSec.toFixed(1)}/s · {Math.floor(crystals)}/{Math.floor(crystalCap)}
        </span>
      </div>

      {pendingCrystals.length === 0 ? (
        <div className="flex-1 flex flex-col items-center justify-center text-center gap-3 rounded-2xl border border-dashed border-white/10 bg-black/20 p-6">
          <div className="relative h-16 w-16">
            <div className="absolute inset-0 rounded-full bg-rose-500/20 blur-xl animate-pulse" />
            <div className="absolute inset-2 rounded-full border-2 border-rose-400/40 rotate-45" />
            <div className="absolute inset-4 rounded-full bg-rose-500/30" />
          </div>
          <p className="text-sm text-muted-foreground">
            晶体正在生成中…
          </p>
          <p className="text-xs text-muted-foreground/70 max-w-[220px]">
            自治无人机每数秒回收一颗记忆晶体，点击下方晶体开启解码。
          </p>
        </div>
      ) : (
        <div className="flex-1 grid grid-cols-2 sm:grid-cols-3 gap-3 content-start max-h-[420px] overflow-y-auto echo-scroll pr-1">
          {pendingCrystals.map((c) => (
            <CrystalCard key={c.id} crystal={c} onClick={() => startDecode(c.id)} />
          ))}
        </div>
      )}
      <style jsx global>{`
        .echo-scroll::-webkit-scrollbar { width: 6px; }
        .echo-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }
        .echo-scroll::-webkit-scrollbar-track { background: transparent; }
      `}</style>
    </div>
  );
}

function CrystalCard({
  crystal,
  onClick,
}: {
  crystal: { id: string; tier: 1 | 2 | 3; value: number };
  onClick: () => void;
}) {
  const tierColor =
    crystal.tier === 1 ? "#34d399" : crystal.tier === 2 ? "#fbbf24" : "#e879f9";
  const tierLabel = crystal.tier === 1 ? "常见" : crystal.tier === 2 ? "稀有" : "史诗";
  return (
    <button
      onClick={onClick}
      className="group relative aspect-square rounded-2xl border border-white/10 bg-black/40 hover:border-white/30 transition-all duration-300 hover:scale-[1.03] focus:outline-none overflow-hidden"
      style={{ boxShadow: `inset 0 0 24px ${tierColor}22` }}
    >
      {/* 晶体图形 */}
      <div className="absolute inset-0 flex items-center justify-center">
        <div
          className="relative h-12 w-12 transition-transform duration-500 group-hover:rotate-180"
          style={{ filter: `drop-shadow(0 0 12px ${tierColor}88)` }}
        >
          <div
            className="absolute inset-0 rotate-45 rounded-md"
            style={{
              background: `linear-gradient(135deg, ${tierColor}, ${tierColor}66)`,
              border: `1px solid ${tierColor}`,
            }}
          />
          <div
            className="absolute inset-2 rotate-45 rounded-sm"
            style={{ background: `linear-gradient(135deg, rgba(255,255,255,0.5), transparent)` }}
          />
        </div>
      </div>
      {/* 标签 */}
      <div className="absolute top-1.5 left-1.5 text-[10px] font-mono px-1.5 py-0.5 rounded bg-black/50" style={{ color: tierColor }}>
        T{crystal.tier}
      </div>
      <div className="absolute bottom-1.5 right-1.5 text-[10px] text-white/70">
        {tierLabel}
      </div>
      <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-center pb-2">
        <span className="text-[11px] font-medium text-white">解码 →</span>
      </div>
    </button>
  );
}
