import { TRPCError } from "@trpc/server";
import { describe, expect, it, vi } from "vitest";
import {
  buildSelfServiceTimelineInput,
  buildTimelineEntriesDetailInput,
  createTimelineDateRange,
  createTimelineFilters,
} from "../router/timeline-filter-support.js";

describe("timeline filter support", () => {
  it("builds date ranges and rejects inverted ranges", () => {
    expect(
      createTimelineDateRange({
        startDate: "2026-04-01",
        durationDays: 3,
      }),
    ).toEqual({
      startDate: new Date("2026-04-01T00:00:00.000Z"),
      endDate: new Date("2026-04-03T00:00:00.000Z"),
    });

    expect(() =>
      createTimelineDateRange({
        startDate: "2026-04-03",
        endDate: "2026-04-01",
      }),
    ).toThrowError(new TRPCError({
      code: "BAD_REQUEST",
      message: "endDate must be on or after startDate.",
    }));
  });

  it("normalizes timeline filters and assembles detail input", () => {
    expect(
      createTimelineFilters({
        resourceIds: [" resource_1 ", ""],
        projectIds: ["project_1"],
        chapters: [" Compositing "],
      }),
    ).toEqual({
      resourceIds: ["resource_1"],
      projectIds: ["project_1"],
      clientIds: undefined,
      chapters: ["Compositing"],
      eids: undefined,
      countryCodes: undefined,
    });

    expect(
      buildTimelineEntriesDetailInput({
        startDate: "2026-04-01",
        durationDays: 3,
        resourceIds: [" resource_1 ", ""],
        projectIds: ["project_1"],
        chapters: [" Compositing "],
      }),
    ).toEqual({
      period: {
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-03T00:00:00.000Z"),
      },
      filters: {
        resourceIds: ["resource_1"],
        projectIds: ["project_1"],
        clientIds: undefined,
        chapters: ["Compositing"],
        eids: undefined,
        countryCodes: undefined,
      },
      timelineInput: {
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-03T00:00:00.000Z"),
        resourceIds: ["resource_1"],
        projectIds: ["project_1"],
        clientIds: undefined,
        chapters: ["Compositing"],
        eids: undefined,
        countryCodes: undefined,
      },
    });
  });

  it("builds self-service timeline input only for owned resources", async () => {
    const ctx = {
      dbUser: { id: "user_1" },
      db: {
        resource: {
          findFirst: vi.fn().mockResolvedValue({ id: "resource_1" }),
        },
      },
    };

    await expect(
      buildSelfServiceTimelineInput(ctx as never, {
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-03T00:00:00.000Z"),
        projectIds: [" project_1 "],
        clientIds: [" client_1 "],
      }),
    ).resolves.toEqual({
      startDate: new Date("2026-04-01T00:00:00.000Z"),
      endDate: new Date("2026-04-03T00:00:00.000Z"),
      resourceIds: ["resource_1"],
      projectIds: ["project_1"],
      clientIds: ["client_1"],
    });

    await expect(
      buildSelfServiceTimelineInput({
        dbUser: { id: "user_2" },
        db: {
          resource: {
            findFirst: vi.fn().mockResolvedValue(null),
          },
        },
      } as never, {
        startDate: new Date("2026-04-01T00:00:00.000Z"),
        endDate: new Date("2026-04-03T00:00:00.000Z"),
      }),
    ).resolves.toBeNull();
  });
});
