import assert from "node:assert/strict";
import test from "node:test";

import type { ApiResult, HwpodNodeOpsResponse, HwpodSpecsResponse, LiveProbePayload, LiveSurface } from "../src/types/index.ts";
import { traceExplorerHref } from "../src/config/runtime.ts";
import { summarizeBuilds, summarizeHwpodNodeOps, summarizeProbeRows } from "../src/stores/workbench-live.ts";
import { liveCall } from "../src/stores/workbench.ts";

Object.defineProperty(globalThis, "window", {
  configurable: true,
  value: {
    HWLAB_CLOUD_WEB_CONFIG: {
      displayTime: { timeZone: "Asia/Shanghai", locale: "zh-CN", label: "北京时间" }
    }
  }
});

test("R3 probe summary exposes React WorkbenchProbe rows", () => {
  const summary = summarizeProbeRows(liveSurface());
  assert.equal(summary.rows.length, 3);
  assert.equal(summary.okCount, 3);
  assert.equal(summary.tone, "ok");
  assert.ok(summary.rows.some((row) => row.path === "/health/live" && row.detail.includes("revision=c0cbdbb38d")));
});

test("R3 build summary maps live-builds services instead of raw JSON", () => {
  const summary = summarizeBuilds(liveSurface());
  assert.equal(summary.rows.length, 2);
  assert.equal(summary.tone, "warn");
  assert.match(summary.countsText ?? "", /服务 2 个/);
  assert.ok(summary.rows.some((row) => row.label === "hwlab-cloud-web" && row.reason?.includes("构建时间不可用")));
});

test("R3 HWPOD summary combines specs availability, node-ops and blocker stream", () => {
  const summary = summarizeHwpodNodeOps({ live: liveSurface() });
  assert.equal(summary.contractVersion, "hwpod-node-ops-v1");
  assert.equal(summary.hwpodName, "d601-f103-v2");
  assert.equal(summary.nodeId, "node-d601-f103-v2");
  assert.equal(summary.supportedOpsCount, 3);
  assert.equal(summary.connectedCount, 0);
  assert.ok(summary.tiles.some((tile) => tile.label === "Contract"));
  assert.ok(summary.tiles.some((tile) => tile.label === "Ops"));
  assert.ok(summary.errors.some((error) => error.code === "hwpod_node_unavailable"));
  assert.ok(summary.streamLines.some((line) => line.includes("op_01_workspace_ls workspace.ls hwpod_node_unavailable")));
});

test("R3 live refresh keeps partial evidence when one endpoint throws", async () => {
  const failed = await liveCall("live builds", async () => {
    throw new Error("network edge reset");
  });
  assert.equal(failed.ok, false);
  assert.equal(failed.status, 0);
  assert.match(failed.error ?? "", /live builds: network edge reset/);

  const passed = await liveCall("health/live", async () => ok<LiveProbePayload>({ status: "ok", revision: "155530d8d9355887a23a08e341291994cc312f54" }));
  assert.equal(passed.ok, true);
  assert.equal(passed.data?.revision, "155530d8d9355887a23a08e341291994cc312f54");
});

test("R3 trace explorer href is config gated and trace_id only", () => {
  window.HWLAB_CLOUD_WEB_CONFIG = {
    displayTime: { timeZone: "Asia/Shanghai", locale: "zh-CN", label: "北京时间" },
    workbench: { traceExplorerUrlTemplate: "/v1/workbench/traces/{trace_id}/events" }
  };
  assert.equal(traceExplorerHref("trc_completed"), "/v1/workbench/traces/trc_completed/events");
  assert.equal(traceExplorerHref("bad/trace"), null);

  window.HWLAB_CLOUD_WEB_CONFIG.workbench = { traceExplorerUrlTemplate: "/trace/{trace_id}?prompt={prompt}" };
  assert.equal(traceExplorerHref("trc_completed"), null);

  window.HWLAB_CLOUD_WEB_CONFIG.workbench = {};
  assert.equal(traceExplorerHref("trc_completed"), null);
});

function liveSurface(): LiveSurface {
  const liveProbe = ok<LiveProbePayload>({ serviceId: "hwlab-cloud-api", environment: "v03", status: "ok", ready: true, revision: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd", observedAt: "2026-06-13T17:59:15.000Z" });
  return {
    healthLive: liveProbe,
    health: ok({ serviceId: "hwlab-edge-proxy", status: "ok", ready: true, revision: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }),
    restIndex: ok({ serviceId: "hwlab-cloud-api", status: "ok", ready: true, revision: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }),
    hwpodSpecs: ok<HwpodSpecsResponse>({ ok: true, status: "completed", count: 1, availableCount: 0, nodeOpsContractVersion: "hwpod-node-ops-v1", specs: [{ name: "d601-f103-v2", hwpodId: "d601-f103-v2", nodeId: "node-d601-f103-v2", workspacePath: "F:\\Work\\D601-HWLAB", source: { caseId: "d601-f103-v2-compile" }, availability: { ok: false, status: "blocked", checkedAt: "2026-06-13T17:59:15.785Z", results: [{ opId: "op_01_workspace_ls", op: "workspace.ls", ok: false, status: "blocked", blocker: { code: "hwpod_node_unavailable", layer: "hwpod-node", retryable: true, summary: "no outbound WebSocket hwpod-node is connected" } }] } }] }),
    hwpodNodeOps: ok<HwpodNodeOpsResponse>({ ok: true, status: "ready", contractVersion: "hwpod-node-ops-v1", route: "/v1/hwpod-node-ops", supportedOps: ["node.health", "workspace.ls", "debug.build"], websocket: { connectedCount: 0, pendingCount: 0, nodes: [] } }),
    liveBuilds: ok({ status: "ok", counts: { total: 2, withBuildTime: 0, unavailable: 2, external: 0 }, services: [{ serviceId: "hwlab-cloud-api", status: "build_time_unavailable", build: { createdAt: null, unavailableReason: "构建时间不可用：live tag 与 deploy metadata 不匹配", metadataSource: "live-health" }, image: { tag: "env-abc", digest: "sha256:abcdef0123456789" }, commit: { id: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }, revision: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }, { serviceId: "hwlab-cloud-web", status: "build_time_unavailable", build: { createdAt: null, unavailableReason: "构建时间不可用：live tag 与 deploy metadata 不匹配" }, image: { tag: "env-web" }, commit: { id: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }, revision: "c0cbdbb38de77f1ecc9d1222438a13294d81d4dd" }] }),
    loadedAt: "2026-06-13T18:00:00.000Z"
  };
}

function ok<T>(data: T): ApiResult<T> {
  return { ok: true, status: 200, data, error: null };
}
