import { describe, expect, it } from "vitest";
import { normalizeFileTreeSelectionForVisibleRows, reduceFileTreeSelection } from "./selection";

describe("reduceFileTreeSelection", () => {
  const visible = ["a", "b", "c", "d"];

  it("单击：清空并仅选中当前；更新 anchor/focus", () => {
    const next = reduceFileTreeSelection(
      { selectedRowIds: new Set(["x"]), anchorRowId: "x", focusedRowId: "x" },
      { type: "click", rowId: "b", visibleRowIds: visible, modifiers: {} },
    );
    expect(Array.from(next.selectedRowIds)).toEqual(["b"]);
    expect(next.anchorRowId).toBe("b");
    expect(next.focusedRowId).toBe("b");
  });

  it("Ctrl/Cmd+单击：切换选中；不清空其他", () => {
    const next = reduceFileTreeSelection(
      { selectedRowIds: new Set(["b"]), anchorRowId: "b", focusedRowId: "b" },
      { type: "click", rowId: "d", visibleRowIds: visible, modifiers: { ctrlKey: true } },
    );
    expect(next.selectedRowIds.has("b")).toBe(true);
    expect(next.selectedRowIds.has("d")).toBe(true);
  });

  it("Shift+单击：按 visibleRows 做区间选择（覆盖式）", () => {
    const next = reduceFileTreeSelection(
      { selectedRowIds: new Set(["b"]), anchorRowId: "b", focusedRowId: "b" },
      { type: "click", rowId: "d", visibleRowIds: visible, modifiers: { shiftKey: true } },
    );
    expect(Array.from(next.selectedRowIds)).toEqual(["b", "c", "d"]);
    expect(next.focusedRowId).toBe("d");
  });

  it("右键：未选中项右键 → 先切为单选；已选中项 → 保持多选集合", () => {
    const a = reduceFileTreeSelection(
      { selectedRowIds: new Set(["b", "c"]), anchorRowId: "b", focusedRowId: "c" },
      { type: "contextmenu", rowId: "d" },
    );
    expect(Array.from(a.selectedRowIds)).toEqual(["d"]);

    const b = reduceFileTreeSelection(
      { selectedRowIds: new Set(["b", "c"]), anchorRowId: "b", focusedRowId: "c" },
      { type: "contextmenu", rowId: "c" },
    );
    expect(Array.from(b.selectedRowIds).sort()).toEqual(["b", "c"]);
    expect(b.focusedRowId).toBe("c");
  });

  it("空白处单击清空选择", () => {
    const next = reduceFileTreeSelection(
      { selectedRowIds: new Set(["b"]), anchorRowId: "b", focusedRowId: "b" },
      { type: "clear" },
    );
    expect(next.selectedRowIds.size).toBe(0);
    expect(next.anchorRowId).toBeNull();
    expect(next.focusedRowId).toBeNull();
  });

  it("可见行变化时保留仍可见的选择", () => {
    const next = normalizeFileTreeSelectionForVisibleRows(
      { selectedRowIds: new Set(["b", "x"]), anchorRowId: "b", focusedRowId: "x" },
      ["a", "b", "c"],
    );
    expect(Array.from(next.selectedRowIds)).toEqual(["b"]);
    expect(next.anchorRowId).toBe("b");
    expect(next.focusedRowId).toBe("b");
  });
});
