import { useCallback, useEffect, useRef, useState, type ReactNode } from "react";
import { getStatus, type StatusItem, type SystemStatus, type ToolInfo } from "../api";

const REFRESH_SEC = 5;

const SERVICE_META: Record<string, { role: string; icon: IconName }> = {
  gateway: { role: "HTTP 接入层 · 鉴权 / 限流 / SSE", icon: "gateway" },
  dispatcher: { role: "编排执行 · Eino 图引擎", icon: "cpu" },
  "mcp-go": { role: "Go I/O 工具 · RAG / 记忆 / 报告", icon: "tool" },
  "mcp-py": { role: "Python 算法工具 · 沙箱 / 解析", icon: "box" },
};
const INFRA_META: Record<string, { role: string; port: string; icon: IconName }> = {
  postgres: { role: "关系库", port: "5432", icon: "db" },
  redis: { role: "缓存 / 限流", port: "6379", icon: "db" },
  nats: { role: "消息总线 · JetStream", port: "4222", icon: "bus" },
  milvus: { role: "向量库", port: "19530", icon: "db" },
  neo4j: { role: "图数据库", port: "7687", icon: "bus" },
};

function toolCategory(t: string): string {
  if (t.startsWith("memory_")) return "记忆";
  if (t.startsWith("kb_") || t.startsWith("wiki_")) return "知识库 / 检索";
  if (t.startsWith("report_")) return "报告";
  if (t.startsWith("history_")) return "会话历史";
  if (t.startsWith("external_")) return "外部接入";
  if (["run_code", "secure_sandbox", "parse_document"].includes(t)) return "算法 / 沙箱";
  return "系统";
}
const CAT_ORDER = ["知识库 / 检索", "记忆", "报告", "会话历史", "外部接入", "算法 / 沙箱", "系统"];
// 能力域配色（工具小卡片的圆点 + 角标）。
const CAT_STYLE: Record<string, { dot: string; chip: string }> = {
  "知识库 / 检索": { dot: "bg-violet-500", chip: "bg-violet-50 text-violet-600" },
  记忆: { dot: "bg-cyan-500", chip: "bg-cyan-50 text-cyan-600" },
  报告: { dot: "bg-amber-500", chip: "bg-amber-50 text-amber-600" },
  会话历史: { dot: "bg-emerald-500", chip: "bg-emerald-50 text-emerald-600" },
  外部接入: { dot: "bg-rose-500", chip: "bg-rose-50 text-rose-600" },
  "算法 / 沙箱": { dot: "bg-indigo-500", chip: "bg-indigo-50 text-indigo-600" },
  系统: { dot: "bg-gray-400", chip: "bg-gray-100 text-gray-500" },
};
const latTone = (ms?: number) => (ms == null ? "text-gray-400" : ms < 50 ? "text-emerald-600" : ms < 200 ? "text-amber-600" : "text-rose-500");

// 数据流动光点 + 节点辉光的关键帧（注入一次）。
const FLOW_CSS = `
@keyframes sdxFlow { 0%{left:-6%;opacity:0} 12%{opacity:1} 88%{opacity:1} 100%{left:106%;opacity:0} }
@keyframes sdxGlow { 0%,100%{opacity:.55} 50%{opacity:1} }
`;

export function StatusPage() {
  const [data, setData] = useState<SystemStatus | null>(null);
  const [err, setErr] = useState("");
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [auto, setAuto] = useState(true);
  const [countdown, setCountdown] = useState(REFRESH_SEC);
  const autoRef = useRef(auto);
  autoRef.current = auto;

  const load = useCallback(async () => {
    setBusy(true);
    try {
      setData(await getStatus());
      setErr("");
    } catch (e) {
      setErr((e as Error).message);
    } finally {
      setLoading(false);
      setBusy(false);
      setCountdown(REFRESH_SEC);
    }
  }, []);

  useEffect(() => {
    void load();
  }, [load]);

  useEffect(() => {
    const id = window.setInterval(() => {
      if (!autoRef.current) return;
      setCountdown((c) => {
        if (c <= 1) {
          void load();
          return REFRESH_SEC;
        }
        return c - 1;
      });
    }, 1000);
    return () => window.clearInterval(id);
  }, [load]);

  const svc = (n: string) => data?.services.find((s) => s.name === n);
  const infra = (n: string) => data?.infra.find((s) => s.name === n);

  if (loading && !data) return <div className="text-sm text-gray-400">加载中…</div>;
  if (!data) return <div className="text-sm text-rose-500">拉取失败：{err}</div>;

  const servicesUp = data.services.filter((s) => s.up).length;
  const infraUp = data.infra.filter((s) => s.up).length;
  const toolCount = data.tools.reduce((n, g) => n + (g.up ? g.tools?.length ?? 0 : 0), 0);
  const downCount = data.services.filter((s) => !s.up).length + data.infra.filter((s) => !s.up).length;
  const allUp = downCount === 0;
  const lats = data.services.filter((s) => s.up && s.latency_ms != null).map((s) => s.latency_ms as number);
  const avgLat = lats.length ? Math.round(lats.reduce((a, b) => a + b, 0) / lats.length) : null;

  return (
    <div className="space-y-5">
      {/* 概览：状态 + 数字层次 + 控制（中性底，绿色只作状态点） */}
      <section className="rounded-2xl border border-gray-200/70 bg-white p-6">
        <div className="flex flex-wrap items-center gap-4">
          <span className={`relative flex h-2.5 w-2.5 ${allUp ? "" : ""}`}>
            <span className={`absolute inline-flex h-full w-full animate-ping rounded-full opacity-60 ${allUp ? "bg-emerald-400" : "bg-amber-400"}`} />
            <span className={`relative inline-flex h-2.5 w-2.5 rounded-full ${allUp ? "bg-emerald-500" : "bg-amber-500"}`} />
          </span>
          <div className="mr-auto">
            <div className="text-lg font-semibold tracking-tight text-gray-900">{allUp ? "系统运行正常" : `${downCount} 项异常`}</div>
            <div className="text-xs text-gray-400">{allUp ? "所有应用服务与基建均已就绪" : "部分组件未就绪，见下方明细"}</div>
          </div>
          <div className="flex items-center gap-2 text-xs">
            <button
              onClick={() => setAuto((a) => !a)}
              className={`rounded-full px-3 py-1.5 font-medium transition ${auto ? "bg-emerald-50 text-emerald-600" : "bg-gray-100 text-gray-400"}`}
            >
              {auto ? `自动刷新 · ${countdown}s` : "已暂停"}
            </button>
            <button
              onClick={() => void load()}
              className="flex items-center gap-1.5 rounded-full bg-gray-900 px-3.5 py-1.5 font-medium text-white transition hover:bg-gray-700"
            >
              <Icon name="refresh" className={`h-3.5 w-3.5 ${busy ? "animate-spin" : ""}`} />
              刷新
            </button>
          </div>
        </div>

        {/* 数字层次：大号数字 + 小标签，竖线分隔，不再用边框盒子 */}
        <div className="mt-6 grid grid-cols-2 divide-x divide-gray-100 sm:grid-cols-5">
          <BigStat value={`${servicesUp}/${data.services.length}`} label="应用服务" bad={servicesUp !== data.services.length} />
          <BigStat value={`${infraUp}/${data.infra.length}`} label="基建环境" bad={infraUp !== data.infra.length} />
          <BigStat value={toolCount} label="注册工具" />
          <BigStat value={avgLat != null ? `${avgLat}ms` : "—"} label="平均探针延迟" />
          <BigStat value={new Date(data.checked_at).toLocaleTimeString("zh-CN", { hour12: false })} label="最后检查" muted />
        </div>
      </section>

      {/* 请求链路：实时数据管道（深色科技底 + 节点辉光 + 流动光点） */}
      <section
        className="relative overflow-hidden rounded-2xl border border-slate-800 bg-slate-950 p-6"
        style={{
          backgroundImage:
            "radial-gradient(circle at 1px 1px, rgba(148,163,184,0.10) 1px, transparent 0), radial-gradient(60% 120% at 50% 0%, rgba(124,58,237,0.18), transparent 70%)",
          backgroundSize: "22px 22px, 100% 100%",
        }}
      >
        <style>{FLOW_CSS}</style>
        <div className="flex items-baseline gap-2.5">
          <h3 className="text-sm font-semibold tracking-tight text-slate-100">请求链路</h3>
          <span className="text-xs text-slate-500">桌面端 / 管理端 → 网关 → 总线 → 调度 → 工具层 · 实时</span>
        </div>
        <div className="mt-5 flex items-center overflow-x-auto pb-1">
          <FlowNode icon="monitor" label="客户端" sub="桌面端 / 管理端" up />
          <Link up={svc("gateway")?.up} />
          <FlowNode icon="gateway" label="网关" sub=":8080" up={svc("gateway")?.up} latency={svc("gateway")?.latency_ms} />
          <Link up={infra("nats")?.up} />
          <FlowNode icon="bus" label="NATS 总线" sub="JetStream" up={infra("nats")?.up} />
          <Link up={svc("dispatcher")?.up} />
          <FlowNode icon="cpu" label="调度中心" sub="Dispatcher" up={svc("dispatcher")?.up} latency={svc("dispatcher")?.latency_ms} />
          <Link up={svc("mcp-go")?.up || svc("mcp-py")?.up} />
          <FlowNode
            icon="tool"
            label="MCP 工具层"
            sub="mcp-go · mcp-py"
            up={Boolean(svc("mcp-go")?.up && svc("mcp-py")?.up)}
            partial={Boolean((svc("mcp-go")?.up || svc("mcp-py")?.up) && !(svc("mcp-go")?.up && svc("mcp-py")?.up))}
            latency={Math.max(svc("mcp-go")?.latency_ms ?? 0, svc("mcp-py")?.latency_ms ?? 0) || undefined}
          />
        </div>
      </section>

      {/* 应用服务 ‖ 基建环境 */}
      <div className="grid grid-cols-1 gap-5 lg:grid-cols-5">
        <section className="rounded-2xl border border-gray-200/70 bg-white p-6 lg:col-span-3">
          <SectionHead title="应用服务" hint="进程存活 · 探针耗时" />
          <div className="mt-4 grid grid-cols-1 gap-px overflow-hidden rounded-xl border border-gray-100 bg-gray-100 sm:grid-cols-2">
            {data.services.map((s) => (
              <ServiceRow key={s.name} item={s} />
            ))}
          </div>
        </section>

        <section className="rounded-2xl border border-gray-200/70 bg-white p-6 lg:col-span-2">
          <SectionHead title="基建环境" hint="5 个依赖" />
          <div className="mt-4 divide-y divide-gray-100">
            {data.infra.map((s) => (
              <InfraRow key={s.name} item={s} />
            ))}
          </div>
        </section>
      </div>

      {/* MCP 工具注册 */}
      <section className="rounded-2xl border border-gray-200/70 bg-white p-6">
        <SectionHead title="MCP 工具注册" hint="各 MCP 服务在线时上报、按能力域分组" />
        <div className="mt-4 space-y-5">
          {data.tools.map((g) => (
            <ToolServer key={g.server} server={g.server} up={g.up} tools={g.tools ?? []} />
          ))}
        </div>
      </section>
    </div>
  );
}

// ---- 子组件 ----

function SectionHead({ title, hint }: { title: string; hint: string }) {
  return (
    <div className="flex items-baseline gap-2.5">
      <h3 className="text-sm font-semibold tracking-tight text-gray-900">{title}</h3>
      <span className="text-xs text-gray-400">{hint}</span>
    </div>
  );
}

function BigStat({ value, label, bad, muted }: { value: string | number; label: string; bad?: boolean; muted?: boolean }) {
  return (
    <div className="px-4 first:pl-0">
      <div className={`text-2xl font-semibold tracking-tight ${bad ? "text-rose-500" : muted ? "text-gray-500" : "text-gray-900"}`}>{value}</div>
      <div className="mt-0.5 text-[11px] text-gray-400">{label}</div>
    </div>
  );
}

function Dot({ up, partial }: { up?: boolean; partial?: boolean }) {
  const c = up ? "bg-emerald-500" : partial ? "bg-amber-500" : "bg-rose-500";
  return <span className={`inline-block h-2 w-2 shrink-0 rounded-full ${c}`} />;
}

function FlowNode({
  icon,
  label,
  sub,
  up,
  partial,
  latency,
}: {
  icon: IconName;
  label: string;
  sub: string;
  up?: boolean;
  partial?: boolean;
  latency?: number;
}) {
  const down = !up && !partial;
  const accent = down ? "text-rose-400" : partial ? "text-amber-300" : "text-emerald-300";
  const ring = down ? "ring-rose-500/40" : partial ? "ring-amber-400/40" : "ring-emerald-400/30";
  const glow = down
    ? "shadow-[0_0_18px_-4px_rgba(244,63,94,0.5)]"
    : partial
      ? "shadow-[0_0_18px_-4px_rgba(245,158,11,0.45)]"
      : "shadow-[0_0_22px_-6px_rgba(16,185,129,0.55)]";
  return (
    <div className={`relative flex min-w-[116px] flex-1 flex-col items-center rounded-xl bg-white/[0.04] px-3 py-3.5 text-center ring-1 ${ring} ${glow} backdrop-blur-sm`}>
      <span className="absolute right-2.5 top-2.5 flex h-2 w-2">
        <span
          className={`absolute inline-flex h-full w-full rounded-full ${down ? "bg-rose-500" : partial ? "bg-amber-400" : "bg-emerald-400"}`}
          style={{ animation: "sdxGlow 1.6s ease-in-out infinite" }}
        />
        <span className={`relative inline-flex h-2 w-2 rounded-full ${down ? "bg-rose-500" : partial ? "bg-amber-400" : "bg-emerald-400"}`} />
      </span>
      <Icon name={icon} className={`mb-1.5 h-5 w-5 ${accent}`} />
      <div className="text-xs font-semibold text-slate-100">{label}</div>
      <div className="text-[10px] text-slate-400">{sub}</div>
      {latency != null && <div className={`mt-1 font-mono text-[10px] ${down ? "text-rose-300" : "text-emerald-300/90"}`}>{latency}ms</div>}
    </div>
  );
}

// Link：连接线 + 沿线流动的数据光点（up 才流动；down 显示红色静态虚线）。
function Link({ up }: { up?: boolean }) {
  if (!up) {
    return (
      <div className="relative mx-1 h-px min-w-[28px] flex-1 self-center bg-gradient-to-r from-rose-500/30 via-rose-500/40 to-rose-500/30" />
    );
  }
  return (
    <div className="relative mx-1 h-5 min-w-[28px] flex-1 self-center">
      {/* 基线 */}
      <div className="absolute left-0 right-0 top-1/2 h-px -translate-y-1/2 bg-gradient-to-r from-emerald-400/20 via-cyan-400/30 to-emerald-400/20" />
      {/* 流动光点（多个 + 错峰延迟 → 数据流动感） */}
      {[0, 0.53, 1.06].map((d, i) => (
        <span
          key={i}
          className="absolute top-1/2 h-1.5 w-1.5 -translate-y-1/2 rounded-full bg-cyan-300 shadow-[0_0_8px_2px_rgba(34,211,238,0.7)]"
          style={{ animation: `sdxFlow 1.6s linear ${d}s infinite` }}
        />
      ))}
    </div>
  );
}

function ServiceRow({ item }: { item: StatusItem }) {
  const meta = SERVICE_META[item.name];
  return (
    <div className="bg-white p-4">
      <div className="flex items-center gap-3">
        <div className={`flex h-9 w-9 shrink-0 items-center justify-center rounded-lg ${item.up ? "bg-gray-50 text-gray-500" : "bg-rose-50 text-rose-500"}`}>
          <Icon name={meta?.icon ?? "tool"} className="h-4 w-4" />
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2">
            <span className="text-sm font-semibold text-gray-900">{item.name}</span>
            <Dot up={item.up} />
            <span className={`text-[11px] ${item.up ? "text-emerald-600" : "text-rose-500"}`}>{item.up ? "运行中" : "离线"}</span>
            {item.up && item.latency_ms != null && <span className={`ml-auto font-mono text-[11px] ${latTone(item.latency_ms)}`}>{item.latency_ms}ms</span>}
          </div>
          <div className="mt-0.5 truncate text-[11px] text-gray-400" title={meta?.role}>{meta?.role}</div>
        </div>
      </div>
      <div className={`mt-2 truncate text-[11px] ${item.up ? "text-gray-500" : "text-rose-500"}`} title={item.detail}>{item.detail || (item.up ? "在线" : "无响应")}</div>
    </div>
  );
}

function InfraRow({ item }: { item: StatusItem }) {
  const meta = INFRA_META[item.name];
  return (
    <div className="flex items-center gap-3 py-2.5 first:pt-0 last:pb-0">
      <Icon name={meta?.icon ?? "db"} className={`h-4 w-4 shrink-0 ${item.up ? "text-gray-300" : "text-rose-400"}`} />
      <span className="text-sm font-medium text-gray-800">{item.name}</span>
      <span className="text-[11px] text-gray-400">{meta?.role}</span>
      <code className="ml-auto font-mono text-[10px] text-gray-300">:{meta?.port}</code>
      <span className="flex w-12 items-center justify-end gap-1.5">
        <Dot up={item.up} />
        <span className={`text-[11px] ${item.up ? "text-emerald-600" : "text-rose-500"}`}>{item.up ? "就绪" : "离线"}</span>
      </span>
    </div>
  );
}

function ToolServer({ server, up, tools }: { server: string; up: boolean; tools: ToolInfo[] }) {
  const groups: Record<string, ToolInfo[]> = {};
  for (const t of tools) (groups[toolCategory(t.name)] ??= []).push(t);
  const cats = Object.keys(groups).sort((a, b) => CAT_ORDER.indexOf(a) - CAT_ORDER.indexOf(b));

  return (
    <div>
      <div className="mb-3 flex flex-wrap items-center gap-2">
        <Dot up={up} />
        <span className="text-sm font-semibold text-gray-900">{server}</span>
        <span className="text-xs text-gray-400">{up ? `${tools.length} 个工具` : "无响应（未启动？）"}</span>
        {up &&
          cats.map((c) => (
            <span key={c} className="rounded-md bg-gray-50 px-2 py-0.5 text-[10px] text-gray-400">
              {c} <span className="font-semibold text-gray-600">{groups[c].length}</span>
            </span>
          ))}
      </div>
      {up && cats.length > 0 && (
        <div className="space-y-4">
          {cats.map((c) => {
            const cs = CAT_STYLE[c] ?? CAT_STYLE["系统"];
            return (
              <div key={c}>
                <div className="mb-2 flex items-center gap-1.5">
                  <span className={`h-1.5 w-1.5 rounded-full ${cs.dot}`} />
                  <span className="text-[10px] font-semibold uppercase tracking-wider text-gray-400">{c}</span>
                  <span className="text-[10px] text-gray-300">{groups[c].length}</span>
                </div>
                <div className="grid grid-cols-1 gap-2 sm:grid-cols-2 xl:grid-cols-3">
                  {groups[c].map((t) => (
                    <div
                      key={t.name}
                      className="group rounded-xl border border-gray-200/70 bg-white p-3 transition hover:-translate-y-0.5 hover:border-violet-200 hover:shadow-[0_4px_16px_-6px_rgba(124,58,237,0.25)]"
                    >
                      <div className="flex items-center gap-2">
                        <span className={`h-1.5 w-1.5 shrink-0 rounded-full ${cs.dot}`} />
                        <span className="text-xs font-semibold text-gray-800">{t.cn}</span>
                        <code className="ml-auto truncate font-mono text-[10px] text-gray-400">{t.name}</code>
                      </div>
                      <div className="mt-1.5 line-clamp-2 text-[10px] leading-relaxed text-gray-400" title={t.desc}>
                        {t.desc}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ---- 内联图标 ----
type IconName = "refresh" | "monitor" | "gateway" | "bus" | "cpu" | "tool" | "box" | "db";
const PATHS: Record<IconName, string> = {
  refresh: "M21 12a9 9 0 1 1-3-6.7L21 8 M21 3v5h-5",
  monitor: "M3 4h18v12H3z M8 20h8 M12 16v4",
  gateway: "M4 4h16v6H4z M4 14h16v6H4z M8 7h.01 M8 17h.01",
  bus: "M18 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6z M6 15a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M18 16a3 3 0 1 0 0 6 3 3 0 0 0 0-6z M8.6 13.5l6.8 4 M15.4 6.5l-6.8 4",
  cpu: "M6 6h12v12H6z M9 9h6v6H9z M9 1v3 M15 1v3 M9 20v3 M15 20v3 M1 9h3 M1 15h3 M20 9h3 M20 15h3",
  tool: "M14.7 6.3a4 4 0 0 1-5.4 5.4L4 17v3h3l5.3-5.3a4 4 0 0 0 5.4-5.4l-2.7 2.7-2-2 2.7-2.7z",
  box: "M21 8 12 3 3 8v8l9 5 9-5z M3 8l9 5 9-5 M12 13v8",
  db: "M12 3c4.4 0 8 1.3 8 3s-3.6 3-8 3-8-1.3-8-3 3.6-3 8-3z M4 6v6c0 1.7 3.6 3 8 3s8-1.3 8-3V6 M4 12v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6",
};
function Icon({ name, className }: { name: IconName; className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d={PATHS[name]} />
    </svg>
  );
}
