import { describe, expect, it } from "vitest";
import { diffScans } from "../src/scan-diff.js";

const PINNED = new Date("2026-08-07T00:00:00.000Z");

function item(overrides: Partial<Parameters<typeof diffScans>[0][number]> = {}) {
  return {
    id: "prev-1",
    displayName: "Mjölk",
    quantity: 1,
    unit: "LITER",
    storageLocationId: "loc-fridge",
    ...overrides,
  };
}

function obs(overrides: Partial<Parameters<typeof diffScans>[1][number]> = {}) {
  return {
    displayName: "Mjölk",
    quantity: 1,
    unit: "LITER",
    storageLocationId: "loc-fridge",
    observationConfidence: 0.95,
    ...overrides,
  };
}

describe("diffScans", () => {
  it("marks identical items unchanged", () => {
    const result = diffScans([item()], [obs()], PINNED);
    expect(result.rows).toHaveLength(1);
    expect(result.rows[0]?.kind).toBe("unchanged");
    expect(result.pendingVanishedIds).toEqual([]);
  });

  it("detects new item", () => {
    const result = diffScans([], [obs({ displayName: "Ost" })], PINNED);
    expect(result.rows).toHaveLength(1);
    expect(result.rows[0]?.kind).toBe("new_item");
  });

  it("detects vanished item as proposal only", () => {
    const result = diffScans([item()], [], PINNED);
    expect(result.rows).toHaveLength(1);
    expect(result.rows[0]?.kind).toBe("vanished");
    expect(result.pendingVanishedIds).toEqual(["prev-1"]);
  });

  it("detects quantity change", () => {
    const result = diffScans([item()], [obs({ quantity: 0.5 })], PINNED);
    expect(result.rows[0]?.kind).toBe("quantity_changed");
    expect(result.rows[0]?.previousQuantity).toBe(1);
    expect(result.rows[0]?.newQuantity).toBe(0.5);
  });

  it("detects moved item", () => {
    const result = diffScans([item()], [obs({ storageLocationId: "loc-freezer" })], PINNED);
    expect(result.rows[0]?.kind).toBe("moved");
  });

  it("sorts changes before unchanged", () => {
    const result = diffScans(
      [item({ id: "a", displayName: "A" }), item({ id: "b", displayName: "B" })],
      [obs({ displayName: "A", quantity: 0.5 }), obs({ displayName: "B" })],
      PINNED,
    );
    expect(result.rows.map((r) => r.kind)).toEqual(["quantity_changed", "unchanged"]);
  });
});
