import { describe, expect, it, vi } from "vitest";
import {
  loadTimelineEntryRecords,
  resolveTimelineEntryProjectIds,
  resolveTimelineEntryResourceIds,
} from "../router/timeline-entry-query-support.js";

describe("timeline entry query support", () => {
  it("resolves resource ids from direct filters before chapter and geography filters", async () => {
    const db = {
      resource: {
        findMany: vi.fn(),
      },
    };

    await expect(
      resolveTimelineEntryResourceIds(db as never, {
        resourceIds: ["resource_1"],
        chapters: ["Comp"],
        eids: ["E-001"],
        countryCodes: ["DE"],
      }),
    ).resolves.toEqual(["resource_1"]);
    expect(db.resource.findMany).not.toHaveBeenCalled();

    db.resource.findMany.mockResolvedValueOnce([{ id: "resource_2" }, { id: "resource_3" }]);

    await expect(
      resolveTimelineEntryResourceIds(db as never, {
        chapters: ["Comp"],
        eids: ["E-001"],
        countryCodes: ["DE"],
      }),
    ).resolves.toEqual(["resource_2", "resource_3"]);
    expect(db.resource.findMany).toHaveBeenCalledWith({
      where: {
        AND: [
          { chapter: { in: ["Comp"] } },
          { eid: { in: ["E-001"] } },
          { country: { code: { in: ["DE"] } } },
        ],
      },
      select: { id: true },
    });
  });

  it("resolves project ids from client filters and intersects explicit project filters", async () => {
    const db = {
      project: {
        findMany: vi.fn().mockResolvedValue([{ id: "project_1" }, { id: "project_2" }]),
      },
    };

    await expect(
      resolveTimelineEntryProjectIds(db as never, {
        clientIds: ["client_1"],
      }),
    ).resolves.toEqual(["project_1", "project_2"]);

    await expect(
      resolveTimelineEntryProjectIds(db as never, {
        clientIds: ["client_1"],
        projectIds: ["project_2", "project_3"],
      }),
    ).resolves.toEqual(["project_2"]);
  });

  it("loads assignments and skips demands when resource filters are active", async () => {
    const db = {
      resource: {
        findMany: vi.fn().mockResolvedValue([{ id: "resource_1" }]),
      },
      project: {
        findMany: vi.fn().mockResolvedValue([{ id: "project_1" }]),
      },
      demandRequirement: {
        findMany: vi.fn(),
      },
      assignment: {
        findMany: vi.fn().mockResolvedValue([{ id: "assignment_1" }]),
      },
    };

    await expect(
      loadTimelineEntryRecords(db as never, {
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-10T00:00:00.000Z"),
        chapters: ["Comp"],
        clientIds: ["client_1"],
      }),
    ).resolves.toEqual({
      demandRequirements: [],
      assignments: [{ id: "assignment_1" }],
    });

    expect(db.demandRequirement.findMany).not.toHaveBeenCalled();
    expect(db.assignment.findMany).toHaveBeenCalledWith(
      expect.objectContaining({
        where: expect.objectContaining({
          resourceId: { in: ["resource_1"] },
          projectId: { in: ["project_1"] },
        }),
      }),
    );
  });
});
