import { describe, expect, it } from "vitest";
import {
  compareNullableValues,
  type SortConfig,
  sortItems,
  toggleSort,
} from "../../../common/core/utils";

describe("shared sort helpers", () => {
  it("toggles sort direction for the same key", () => {
    expect(toggleSort<string>(null, "name")).toEqual({
      key: "name",
      direction: "asc",
    });

    expect(
      toggleSort<string>({ key: "name", direction: "asc" }, "name"),
    ).toEqual({
      key: "name",
      direction: "desc",
    });

    expect(
      toggleSort<string>({ key: "name", direction: "desc" }, "status"),
    ).toEqual({
      key: "status",
      direction: "asc",
    });
  });

  it("compares nullable values with nulls last", () => {
    expect(compareNullableValues("a", "b", "asc")).toBeLessThan(0);
    expect(compareNullableValues("a", "b", "desc")).toBeGreaterThan(0);
    expect(compareNullableValues(null, "b", "asc")).toBeGreaterThan(0);
    expect(compareNullableValues("b", null, "asc")).toBeLessThan(0);
  });

  it("sorts items with resolver maps", () => {
    const items = [
      {
        id: "2",
        name: "Beta",
        metadata: { score: 2 },
      },
      {
        id: "3",
        name: "gamma",
        metadata: {},
      },
      {
        id: "1",
        name: "alpha",
        metadata: { score: 1 },
      },
    ];

    const nameSort: SortConfig<"name"> = { key: "name", direction: "asc" };
    expect(sortItems(items, nameSort).map((item) => item.id)).toEqual([
      "1",
      "2",
      "3",
    ]);

    const scoreSort: SortConfig<"score"> = { key: "score", direction: "asc" };
    expect(
      sortItems(items, scoreSort, {
        score: (item) =>
          typeof item.metadata.score === "number" ? item.metadata.score : null,
      }).map((item) => item.id),
    ).toEqual(["1", "2", "3"]);
  });
});
