import { describe, expect, it } from "vitest";
import { displayOrder, nextSortState, type SortState } from "@/lib/table-sort";

type Key = "scheduled_at" | "grade" | "monitoring" | "d_security";

describe("nextSortState", () => {
  /** 指示書BH §1-3 — 普通の列（first: asc） */
  it("default → asc on new column", () => {
    expect(nextSortState(null, "grade", { first: "asc", twoState: false })).toEqual({
      key: "grade",
      order: "asc",
    });
  });

  it("other column → asc on clicked column", () => {
    const current: SortState<Key> = { key: "scheduled_at", order: "asc" };
    expect(nextSortState(current, "grade", { first: "asc", twoState: false })).toEqual({
      key: "grade",
      order: "asc",
    });
  });

  it("asc → desc on same column", () => {
    const current: SortState<Key> = { key: "grade", order: "asc" };
    expect(nextSortState(current, "grade", { first: "asc", twoState: false })).toEqual({
      key: "grade",
      order: "desc",
    });
  });

  it("desc → default on same column", () => {
    const current: SortState<Key> = { key: "grade", order: "desc" };
    expect(nextSortState(current, "grade", { first: "asc", twoState: false })).toBeNull();
  });

  /** 2状態列（日付・検知時刻） */
  it("default → asc on two-state column", () => {
    expect(nextSortState(null, "scheduled_at", { first: "asc", twoState: true })).toEqual({
      key: "scheduled_at",
      order: "asc",
    });
  });

  it("asc → default on two-state column", () => {
    const current: SortState<Key> = { key: "scheduled_at", order: "asc" };
    expect(nextSortState(current, "scheduled_at", { first: "asc", twoState: true })).toBeNull();
  });

  it("grade desc → scheduled_at asc（2状態列・指示書BH §1-3）", () => {
    expect(
      nextSortState({ key: "grade", order: "desc" }, "scheduled_at", { first: "asc", twoState: true })
    ).toEqual({ key: "scheduled_at", order: "asc" });
  });

  it("monitoring asc → d_security desc（施設マスタ first: desc）", () => {
    expect(
      nextSortState({ key: "monitoring", order: "asc" }, "d_security", { first: "desc", twoState: false })
    ).toEqual({ key: "d_security", order: "desc" });
  });

  /** 施設マスタ（first: desc） */
  it("facilities cycle: default → desc → asc → default", () => {
    expect(nextSortState(null, "monitoring", { first: "desc", twoState: false })).toEqual({
      key: "monitoring",
      order: "desc",
    });
    const desc: SortState<Key> = { key: "monitoring", order: "desc" };
    expect(nextSortState(desc, "monitoring", { first: "desc", twoState: false })).toEqual({
      key: "monitoring",
      order: "asc",
    });
    const asc: SortState<Key> = { key: "monitoring", order: "asc" };
    expect(nextSortState(asc, "monitoring", { first: "desc", twoState: false })).toBeNull();
  });
});

describe("displayOrder", () => {
  it("null + defaultKey date → desc", () => {
    expect(displayOrder(null, "scheduled_at", "scheduled_at")).toBe("desc");
  });

  it("null + other column → null", () => {
    expect(displayOrder(null, "grade", "scheduled_at")).toBeNull();
  });

  it("active asc on date → asc", () => {
    const state: SortState<Key> = { key: "scheduled_at", order: "asc" };
    expect(displayOrder(state, "scheduled_at", "scheduled_at")).toBe("asc");
  });

  it("active grade asc + date column → null", () => {
    const state: SortState<Key> = { key: "grade", order: "asc" };
    expect(displayOrder(state, "scheduled_at", "scheduled_at")).toBeNull();
  });

  it("null without defaultKey → null", () => {
    expect(displayOrder(null, "monitoring")).toBeNull();
  });
});
