import { describe, expect, it } from "vitest";
import { createMockDb } from "../../../testing/index";
import type { DB } from "../generated/kysely-tailordb";
import { expectOk } from "../testing/commandTestUtils";
import { baseActiveSite, baseStockLevel } from "../testing/fixtures";
import { run } from "./getSiteStockSummary";

describe("getSiteStockSummary", () => {
  it("returns aggregated quantities per item", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce([{ id: "location-1" }]);
    spies.select.mockReturnValueOnce([baseStockLevel]);

    const result = await run(db, { siteId: baseActiveSite.id });
    const { summary } = expectOk<{
      summary: { itemId: string; totalOnHand: string }[];
    }>(result as never);

    expect(summary).toHaveLength(1);
    expect(summary[0].totalOnHand).toBe("100");
  });

  it("correctly sums across multiple locations", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce([{ id: "location-1" }, { id: "location-2" }]);
    spies.select.mockReturnValueOnce([
      baseStockLevel,
      {
        ...baseStockLevel,
        id: "stock-level-2",
        storageLocationId: "location-2",
        onHand: "50",
        reserved: "5",
        incoming: "10",
        blocked: "0",
      },
    ]);

    const result = await run(db, { siteId: baseActiveSite.id });
    const { summary } = expectOk<{
      summary: {
        itemId: string;
        totalOnHand: string;
        totalReserved: string;
        totalIncoming: string;
        totalBlocked: string;
        totalAvailable: string;
      }[];
    }>(result as never);

    expect(summary).toHaveLength(1);
    expect(summary[0].totalOnHand).toBe("150");
    expect(summary[0].totalReserved).toBe("15");
    expect(summary[0].totalIncoming).toBe("30");
    expect(summary[0].totalBlocked).toBe("5");
  });

  it("filters by item when provided", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce([{ id: "location-1" }]);
    spies.select.mockReturnValueOnce([baseStockLevel]);

    const result = await run(db, { siteId: baseActiveSite.id, itemId: "item-1" });
    const { summary } = expectOk<{
      summary: { itemId: string; totalOnHand: string }[];
    }>(result as never);

    expect(summary).toHaveLength(1);
    expect(summary[0].itemId).toBe("item-1");
  });

  it("returns empty summary when site has no active locations", async () => {
    const { db, spies } = createMockDb<DB>();
    spies.select.mockReturnValueOnce([]);

    const result = await run(db, { siteId: "nonexistent-site" });
    const { summary } = expectOk<{ summary: unknown[] }>(result as never);

    expect(summary).toEqual([]);
  });
});
