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

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

import { availabilitySorter, latencySorter, statusSorter } from "../../../src/web/constants/target-table-sorters";

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("statusSorter", () => {
  test("DOWN 排在 UP 前面", () => {
    const up = makeTarget({
      latestCheck: { detail: null, durationMs: 10, failure: null, matched: true, observation: null, timestamp: "" },
    });
    const down = makeTarget({
      latestCheck: { detail: null, durationMs: 10, failure: null, matched: false, observation: null, timestamp: "" },
    });
    expect(statusSorter(down, up)).toBeLessThan(0);
    expect(statusSorter(up, down)).toBeGreaterThan(0);
  });

  test("相同状态返回 0", () => {
    const a = makeTarget({
      latestCheck: { detail: null, durationMs: 10, failure: null, matched: true, observation: null, timestamp: "" },
    });
    const b = makeTarget({
      latestCheck: { detail: null, durationMs: 20, failure: null, matched: true, observation: null, timestamp: "" },
    });
    expect(statusSorter(a, b)).toBe(0);
  });

  test("无 latestCheck 的目标排在最后", () => {
    const noCheck = makeTarget();
    const up = makeTarget({
      latestCheck: { detail: null, durationMs: 10, failure: null, matched: true, observation: null, timestamp: "" },
    });
    expect(statusSorter(noCheck, up)).toBeGreaterThan(0);
  });
});

describe("availabilitySorter", () => {
  test("低可用率排前面", () => {
    const low = makeTarget({ stats: { availability: 95, downChecks: 5, totalChecks: 100, upChecks: 95 } });
    const high = makeTarget({ stats: { availability: 99.9, downChecks: 1, totalChecks: 100, upChecks: 99 } });
    expect(availabilitySorter(low, high)).toBeLessThan(0);
  });

  test("相同可用率返回 0", () => {
    const a = makeTarget({ stats: { availability: 99.9, downChecks: 1, totalChecks: 100, upChecks: 99 } });
    const b = makeTarget({ stats: { availability: 99.9, downChecks: 1, totalChecks: 50, upChecks: 49 } });
    expect(availabilitySorter(a, b)).toBe(0);
  });

  test("无 stats 按 0 处理", () => {
    const noStats = makeTarget({ stats: undefined as unknown as TargetStatus["stats"] });
    const high = makeTarget({ stats: { availability: 99.9, downChecks: 1, totalChecks: 100, upChecks: 99 } });
    expect(availabilitySorter(noStats, high)).toBeLessThan(0);
  });
});

describe("latencySorter", () => {
  test("低延迟排前面", () => {
    const fast = makeTarget({
      latestCheck: { detail: null, durationMs: 50, failure: null, matched: true, observation: null, timestamp: "" },
    });
    const slow = makeTarget({
      latestCheck: { detail: null, durationMs: 200, failure: null, matched: true, observation: null, timestamp: "" },
    });
    expect(latencySorter(fast, slow)).toBeLessThan(0);
  });

  test("无延迟排最后", () => {
    const noLatency = makeTarget({
      latestCheck: { detail: null, durationMs: null, failure: null, matched: true, observation: null, timestamp: "" },
    });
    const hasLatency = makeTarget({
      latestCheck: { detail: null, durationMs: 100, failure: null, matched: true, observation: null, timestamp: "" },
    });
    expect(latencySorter(noLatency, hasLatency)).toBeGreaterThan(0);
  });
});
