import type { PrimaryTableCellParams, PrimaryTableCol } from "tdesign-react";

import { describe, expect, test } from "bun:test";

import type { TargetStatus } from "../../../src/shared/api";

import { createTargetTableColumns } from "../../../src/web/constants/target-table-columns";

interface TableFilter {
  list?: Array<{ label: string; value: string }>;
  type?: string;
}

function getColumn(columns: Array<PrimaryTableCol<TargetStatus>>, colKey: string): PrimaryTableCol<TargetStatus> {
  const column = columns.find((item) => item.colKey === colKey);
  expect(column).toBeDefined();
  return column!;
}

function makeTarget(overrides: Partial<TargetStatus> = {}): TargetStatus {
  return {
    currentStreak: null,
    description: null,
    group: "default",
    id: "1",
    interval: "5s",
    latestCheck: null,
    name: "test",
    recentSamples: [],
    stats: { availability: 100, downChecks: 0, totalChecks: 0, upChecks: 0 },
    target: "https://example.com",
    type: "http",
    ...overrides,
  };
}

describe("createTargetTableColumns", () => {
  test("生成 7 个目标表格列", () => {
    const columns = createTargetTableColumns(["http", "cmd"]);

    expect(columns.map((column) => column.colKey)).toEqual([
      "latestCheck.matched",
      "name",
      "type",
      "stats.availability",
      "recentSamples",
      "currentStreak",
      "latestCheck.durationMs",
    ]);
  });

  test("根据 checkerTypes 生成类型筛选器", () => {
    const typeColumn = getColumn(createTargetTableColumns(["http", "cmd", "tcp"]), "type");
    const filter = typeColumn.filter as TableFilter;

    expect(filter.type).toBe("single");
    expect(filter.list).toEqual([
      { label: "全部", value: "" },
      { label: "http", value: "http" },
      { label: "cmd", value: "cmd" },
      { label: "tcp", value: "tcp" },
    ]);
  });

  test("checkerTypes 为空时只保留全部选项", () => {
    const typeColumn = getColumn(createTargetTableColumns([]), "type");
    const filter = typeColumn.filter as TableFilter;

    expect(filter.list).toEqual([{ label: "全部", value: "" }]);
  });

  test("类型列直接渲染原始 type 文本", () => {
    const typeColumn = getColumn(createTargetTableColumns(["tcp"]), "type");
    const renderCell = typeColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => {
      props: { children: unknown };
    };
    const element = renderCell({
      col: typeColumn,
      colIndex: 2,
      row: makeTarget({ type: "tcp" }),
      rowIndex: 0,
    });

    expect(element.props.children).toBe("tcp");
  });

  test("连续状态列渲染 capped 标记", () => {
    const streakColumn = getColumn(createTargetTableColumns(["http"]), "currentStreak");
    const renderCell = streakColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => {
      props: { children: unknown[] };
    };
    const element = renderCell({
      col: streakColumn,
      colIndex: 5,
      row: makeTarget({ currentStreak: { capped: true, count: 30, up: false } }),
      rowIndex: 0,
    });

    expect(streakColumn.title).toBe("连续(次)");
    expect(element.props.children.join("")).toBe("▼ 30+");
  });

  test("延迟列超过 9999ms 时显示上限文案", () => {
    const latencyColumn = getColumn(createTargetTableColumns(["http"]), "latestCheck.durationMs");
    const renderCell = latencyColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => {
      props: { children: string[]; className: string };
    };
    const element = renderCell({
      col: latencyColumn,
      colIndex: 6,
      row: makeTarget({
        latestCheck: {
          detail: "200",
          durationMs: 12000,
          failure: null,
          matched: true,
          observation: null,
          timestamp: "2026-01-01T00:00:00.000Z",
        },
      }),
      rowIndex: 0,
    });

    expect(element.props.children).toEqual(["9999+", " ms"]);
    expect(element.props.className).toContain("latency-value");
  });

  test("延迟列标题为 延迟", () => {
    const latencyColumn = getColumn(createTargetTableColumns(["http"]), "latestCheck.durationMs");
    expect(latencyColumn.title).toBe("延迟");
  });

  test("延迟列正常值包含 ms 单位", () => {
    const latencyColumn = getColumn(createTargetTableColumns(["http"]), "latestCheck.durationMs");
    const renderCell = latencyColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => {
      props: { children: string[]; className: string };
    };
    const element = renderCell({
      col: latencyColumn,
      colIndex: 6,
      row: makeTarget({
        latestCheck: {
          detail: "200",
          durationMs: 123,
          failure: null,
          matched: true,
          observation: null,
          timestamp: "2026-01-01T00:00:00.000Z",
        },
      }),
      rowIndex: 0,
    });
    expect(element.props.children).toEqual(["123", " ms"]);
  });

  test("名称列无排序配置", () => {
    const nameColumn = getColumn(createTargetTableColumns(["http"]), "name");
    expect(nameColumn.sorter).toBeUndefined();
    expect(nameColumn.sortType).toBeUndefined();
  });

  test("名称列 name 为 null 时显示 id", () => {
    const nameColumn = getColumn(createTargetTableColumns(["http"]), "name");
    const renderCell = nameColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => string;
    const result = renderCell({
      col: nameColumn,
      colIndex: 1,
      row: makeTarget({ id: "my-api", name: null }),
      rowIndex: 0,
    });
    expect(result).toBe("my-api");
  });

  test("名称列 name 有值时显示 name", () => {
    const nameColumn = getColumn(createTargetTableColumns(["http"]), "name");
    const renderCell = nameColumn.cell as (params: PrimaryTableCellParams<TargetStatus>) => string;
    const result = renderCell({
      col: nameColumn,
      colIndex: 1,
      row: makeTarget({ id: "my-api", name: "我的 API" }),
      rowIndex: 0,
    });
    expect(result).toBe("我的 API");
  });
});
