import type { Locator, Page } from "@playwright/test";

import { expect, fakeServerState, test } from "../fixtures/test";

type RequestLedgerEntry = { path?: string; query?: Record<string, string> };
const performanceErrorStatuses = [400, 401, 403, 404, 409, 500] as const;

async function performanceSummaryRequests(page: Page): Promise<RequestLedgerEntry[]> {
  const state = await fakeServerState(page);
  const ledger = Array.isArray(state.requestLedger) ? state.requestLedger : [];
  return ledger.filter((entry): entry is RequestLedgerEntry => Boolean(entry && typeof entry === "object" && (entry as RequestLedgerEntry).path === "/v1/web-performance/summary"));
}

function countWindowRequests(entries: RequestLedgerEntry[], windowId: string): number {
  return entries.filter((entry) => entry.query?.window === windowId).length;
}

test("admin HWPOD groups renders node-ops as structured UI before raw JSON is requested", async ({ page }) => {
  await page.goto("/admin/hwpod-groups");

  await expect(page.getByRole("heading", { name: "HWPOD 分组" })).toBeVisible();
  await expect(page.getByText("hwpod-node-ops-v1")).toBeVisible();
  await expect(page.getByText("/v1/hwpod-node-ops")).toBeVisible();
  await expect(page.getByText("node.health")).toBeVisible();
  await expect(page.getByText("node-d601-f103-v2")).toBeVisible();

  await expect(page.locator("[data-testid='hwpod-raw-json']")).toHaveCount(0);
  await expect(page.locator("body")).not.toContainText('"contractVersion"');

  await page.getByTestId("hwpod-raw-json-toggle").click();
  await expect(page.getByTestId("hwpod-raw-json")).toContainText('"contractVersion"');
});

test("performance dashboard renders Chinese charts and keeps drill-down reachable", async ({ page }) => {
  await page.goto("/performance");

  await expect(page.getByRole("heading", { name: "性能监控", exact: true })).toBeVisible();
  await expect(page.locator(".performance-contract-item")).toHaveCount(5);
  await expect(page.locator(".performance-contract-item").filter({ hasText: "观测窗口" })).toContainText("最近 15 分钟");
  await expect(page.locator(".performance-contract-item").filter({ hasText: "生成时间" })).toContainText("fake-server");
  await expect(page.locator(".performance-contract-item").filter({ hasText: "样本覆盖" })).toContainText("路由");
  await expect(page.locator(".performance-contract-item").filter({ hasText: "数据质量" })).toContainText("低样本阈值 5 个样本");
  await expect(page.locator(".performance-contract-item").filter({ hasText: "统计口径" })).toContainText("精确窗口分位");
  await expect(page.locator(".performance-collection-item")).toHaveCount(4);
  await expect(page.locator(".performance-collection-item").filter({ hasText: "最近样本" })).toContainText("归因字段不完整");
  await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("保留");
  await expect(page.locator(".performance-collection-item").filter({ hasText: "来源组成" })).toContainText("工作台");
  await expect(page.locator(".performance-collection-item").filter({ hasText: "归因完整性" })).toContainText("不完整");
  await expect(page.getByText("工作台归因不完整")).toBeVisible();
  await expect(page.getByText("工作台体感趋势")).toBeVisible();
  await expect(page.getByText("状态分布")).toBeVisible();
  await expect(page.getByText("慢 API TopN")).toBeVisible();
  await expect(page.locator("svg.performance-line-chart")).toHaveCount(3);
  await expect(page.locator(".chart-point")).not.toHaveCount(0);
  await expect(page.locator(".performance-row-contract").filter({ hasText: "桶化估算" }).first()).toBeVisible();
  await expect(page.locator(".performance-row-contract").filter({ hasText: "低样本" }).first()).toBeVisible();
  await expect(page.locator(".performance-row-contract").filter({ hasText: "后端证据" }).first()).toContainText("已匹配后端");
  await expect(page.locator(".performance-row-contract").filter({ hasText: "RUM 慢于后端" }).first()).toBeVisible();
  await expect(page.locator("body")).not.toContainText(/Metric|Route|Count|Status|Samples|Problems|Workbench|Web Vitals|API Timing|Long Tasks/u);
  await expect(page.locator("body")).not.toContainText(/sessionId|traceId|runId|stdout|stderr|Secret/u);

  const windowChecks = [
    { tab: "5 分钟", windowId: "5m", label: "最近 5 分钟" },
    { tab: "15 分钟", windowId: "15m", label: "最近 15 分钟" },
    { tab: "1 小时", windowId: "1h", label: "最近 1 小时" },
    { tab: "6 小时", windowId: "6h", label: "最近 6 小时" },
    { tab: "24 小时", windowId: "24h", label: "最近 24 小时" },
    { tab: "全部", windowId: "all", label: "全部累计" }
  ];
  for (const item of windowChecks) {
    await page.getByRole("tab", { name: item.tab, exact: true }).click();
    await expect(page.locator(".performance-contract-item").filter({ hasText: "观测窗口" })).toContainText(item.label);
  }
  const summaryRequests = await performanceSummaryRequests(page);
  for (const item of windowChecks) expect(countWindowRequests(summaryRequests, item.windowId)).toBeGreaterThan(0);

  const allRequestsBeforeRefresh = countWindowRequests(summaryRequests, "all");
  await page.getByLabel("采集新鲜度").getByRole("button", { name: "刷新" }).click();
  await expect.poll(async () => countWindowRequests(await performanceSummaryRequests(page), "all")).toBeGreaterThan(allRequestsBeforeRefresh);
  await expect(page.locator(".performance-contract-item").filter({ hasText: "观测窗口" })).toContainText("全部累计");

  await page.screenshot({ path: ".state/workbench-e2e/performance-dashboard-desktop.png", fullPage: true });

  await page.setViewportSize({ width: 390, height: 844 });
  await page.goto("/performance");
  await expect(page.getByRole("heading", { name: "性能明细" })).toBeVisible();
  await expect(page.locator("svg.performance-line-chart")).toHaveCount(3);
  await page.screenshot({ path: ".state/workbench-e2e/performance-dashboard-mobile.png", fullPage: true });

  const scrollers = await page.locator(".performance-page .data-table-wrap").evaluateAll((items) => items.map((item) => ({
    clientWidth: Math.round(item.clientWidth),
    scrollWidth: Math.round(item.scrollWidth),
    overflowX: getComputedStyle(item).overflowX
  })));
  expect(scrollers.length).toBeGreaterThanOrEqual(1);
  expect(scrollers.every((item) => item.clientWidth <= 390)).toBeTruthy();
  expect(scrollers.some((item) => item.scrollWidth > item.clientWidth + 120)).toBeTruthy();
  expect(scrollers.every((item) => item.overflowX === "auto" || item.overflowX === "scroll")).toBeTruthy();

  const documentScrollWidth = await page.evaluate(() => Math.round(document.documentElement.scrollWidth));
  expect(documentScrollWidth).toBeLessThanOrEqual(390);
});

test.describe("performance dashboard empty collection", () => {
  test.use({ scenarioId: "performance-empty" });

  test("renders the empty summary contract without invented rows", async ({ page }) => {
    await page.goto("/performance");

    await expect(page.getByRole("heading", { name: "性能监控", exact: true })).toBeVisible();
    await expect(page.locator(".performance-contract-item")).toHaveCount(5);
    await expect(page.locator(".performance-contract-item").filter({ hasText: "样本覆盖" })).toContainText("0 样本");
    await expect(page.locator(".performance-collection-item")).toHaveCount(4);
    await expect(page.locator(".performance-collection-item").filter({ hasText: "最近样本" })).toContainText("采集器尚未上报样本");
    await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("0 样本");
    await expect(page.getByText("暂无采集样本")).toBeVisible();
    await expect(page.getByText("等待数据").first()).toBeVisible();
    await expect(page.getByText("暂无性能样本。请先打开工作台或执行一次真实页面操作后刷新。")).toBeVisible();
    await expect(page.locator(".performance-row-contract")).toHaveCount(0);
  });
});

test.describe("performance dashboard stale current window", () => {
  test.use({ scenarioId: "performance-stale-window" });

  test("keeps retained samples separate from the empty current window", async ({ page }) => {
    await page.goto("/performance");

    await expect(page.getByRole("heading", { name: "性能监控", exact: true })).toBeVisible();
    await expect(page.locator(".performance-contract-item").filter({ hasText: "样本覆盖" })).toContainText("0 样本");
    await expect(page.locator(".performance-collection-item").filter({ hasText: "最近样本" })).toContainText("当前窗口暂无样本");
    await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("0 样本");
    await expect(page.locator(".performance-collection-item").filter({ hasText: "当前窗口样本" })).toContainText("保留 37 样本");
    await expect(page.getByText("当前窗口无样本")).toBeVisible();
    await expect(page.getByText("保留样本存在，但当前窗口没有性能样本。")).toBeVisible();
    await expect(page.locator(".performance-row-contract")).toHaveCount(0);
  });
});

test.describe("performance dashboard summary error", () => {
  test.use({ scenarioId: "performance-summary-error" });

  test("surfaces the summary read-model failure without stale dashboard data", async ({ page }) => {
    await page.goto("/performance");

    await expect(page.getByRole("heading", { name: "性能监控" })).toBeVisible();
    await expect(page.getByText("性能监控加载失败")).toBeVisible();
    await expect(page.getByText("暂时无法连接上游。")).toBeVisible();
    const diagnostic = page.locator(".api-error-diagnostic");
    await expectDiagnosticSummary(diagnostic, "11111111111111111111111111111111");
    await expect(diagnostic).not.toContainText("requestId");
    await expandDiagnostic(diagnostic);
    await expect(diagnostic).toContainText("requestId");
    await expect(diagnostic).toContainText("req_e2e_api_error_diagnostic");
    await expect(diagnostic).toContainText("upstream_unavailable");
    await expect(diagnostic).toContainText("/v1/web-performance/summary");
    await expect(diagnostic).toContainText("valuesPrinted");
    await expect(diagnostic).toContainText("false");
    await expect(page.getByRole("button", { name: "重试" })).toBeVisible();
    await expect(page.locator("body")).not.toContainText(/Code Agent|输入已保留|稍后重试/u);
    await expect(page.locator(".performance-contract-item")).toHaveCount(0);
  });
});

for (const status of performanceErrorStatuses) {
  test.describe(`performance dashboard HTTP ${status} diagnostic`, () => {
    test.use({ scenarioId: `performance-summary-error-${status}` });

    test(`surfaces HTTP ${status} trace diagnostics without stale dashboard data`, async ({ page }) => {
      await page.goto("/performance");

      await expect(page.getByRole("heading", { name: "性能监控", exact: true })).toBeVisible();
      await expect(page.getByText("性能监控加载失败")).toBeVisible();
      const diagnostic = page.locator(".api-error-diagnostic");
      await expectDiagnosticSummary(diagnostic, statusTraceId(status));
      await expect(diagnostic).not.toContainText("requestId");
      await expandDiagnostic(diagnostic);
      await expect(diagnostic).toContainText("requestId");
      await expect(diagnostic).toContainText(`req_e2e_api_status_${status}`);
      await expect(diagnostic).toContainText(`e2e_http_${status}`);
      await expect(diagnostic).toContainText("/v1/web-performance/summary");
      await expect(diagnostic).toContainText(String(status));
      await expect(diagnostic).toContainText("valuesPrinted");
      await expect(diagnostic).toContainText("false");
      await expect(page.getByRole("button", { name: "重试" })).toBeVisible();
      await expect(page.locator(".performance-contract-item")).toHaveCount(0);
    });
  });
}

test.describe("performance dashboard browser network diagnostic", () => {
  test.use({ scenarioId: "performance-network-error" });

  test("surfaces browser generated trace diagnostics when the request has no response", async ({ page }) => {
    await page.goto("/performance");

    await expect(page.getByRole("heading", { name: "性能监控", exact: true })).toBeVisible();
    await expect(page.getByText("性能监控加载失败")).toBeVisible();
    const diagnostic = page.locator(".api-error-diagnostic");
    await expect(diagnostic).toContainText("trace_id");
    await expect(diagnostic.getByRole("button", { name: "诊断详情" })).toHaveAttribute("aria-expanded", "false");
    await expect(diagnostic).not.toContainText("requestId");
    await expandDiagnostic(diagnostic);
    await expect(diagnostic).toContainText("requestId");
    await expect(diagnostic).toContainText("browser_network_error");
    await expect(diagnostic).toContainText("web / network");
    await expect(diagnostic).toContainText("/v1/web-performance/summary");
    await expect(diagnostic).toContainText("browser");
    await expect(diagnostic).toContainText("valuesPrinted");
    await expect(diagnostic).toContainText("false");
    await expect(page.locator(".performance-contract-item")).toHaveCount(0);
  });
});

function statusTraceId(status: number): string {
  return String(status).repeat(11).slice(0, 32);
}

async function expectDiagnosticSummary(diagnostic: Locator, traceId: string): Promise<void> {
  await expect(diagnostic).toContainText(`trace_id=${traceId}`);
  const toggle = diagnostic.getByRole("button", { name: "诊断详情" });
  await expect(toggle).toHaveAttribute("aria-expanded", "false");
  await expect(toggle).toBeVisible();
}

async function expandDiagnostic(diagnostic: Locator): Promise<void> {
  const toggle = diagnostic.getByRole("button", { name: "诊断详情" });
  await toggle.click();
  await expect(toggle).toHaveAttribute("aria-expanded", "true");
}
