import { beforeEach, describe, expect, it, vi } from "vitest";
import { SystemRole } from "@capakraken/shared";

import {
  createToolContext,
  executeTool,
} from "./assistant-tools-holiday-read-test-helpers.js";

describe("assistant holiday resolution calendar preview tools", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("previews resolved holiday calendars for a scope and shows the source calendar", async () => {
    const ctx = createToolContext({
      country: {
        findUnique: vi.fn().mockResolvedValue({
          id: "country_de",
          code: "DE",
          name: "Deutschland",
        }),
      },
      metroCity: {
        findUnique: vi.fn().mockResolvedValue({
          id: "city_augsburg",
          name: "Augsburg",
          countryId: "country_de",
        }),
      },
      holidayCalendar: {
        findMany: vi.fn().mockResolvedValue([
          {
            id: "cal_city",
            name: "Augsburg lokal",
            scopeType: "CITY",
            priority: 5,
            createdAt: new Date("2026-01-01T00:00:00.000Z"),
            entries: [
              {
                id: "entry_1",
                date: new Date("2020-08-08T00:00:00.000Z"),
                name: "Friedensfest lokal",
                isRecurringAnnual: true,
                source: "manual",
              },
            ],
          },
        ]),
      },
    });

    const result = await executeTool(
      "preview_resolved_holiday_calendar",
      JSON.stringify({ countryId: "country_de", metroCityId: "city_augsburg", year: 2026 }),
      ctx,
    );

    const parsed = JSON.parse(result.content) as {
      count: number;
      locationContext: { countryCode: string; metroCity: string | null; year: number };
      holidays: Array<{ name: string; calendarName: string; scope: string; date: string }>;
    };

    expect(parsed.count).toBeGreaterThan(0);
    expect(parsed.locationContext).toEqual(
      expect.objectContaining({
        countryCode: "DE",
        metroCity: "Augsburg",
        year: 2026,
      }),
    );
    expect(parsed.holidays).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          name: "Friedensfest lokal",
          calendarName: "Augsburg lokal",
          scope: "CITY",
          date: "2026-08-08",
        }),
      ]),
    );
    expect(ctx.db.country.findUnique).toHaveBeenCalledWith({
      where: { id: "country_de" },
      select: { id: true, code: true, name: true },
    });
    expect(ctx.db.metroCity.findUnique).toHaveBeenCalledWith({
      where: { id: "city_augsburg" },
      select: { id: true, name: true, countryId: true },
    });
  });

  it("previews resolved holiday calendars through the real holiday router path", async () => {
    const holidayCallerDb = {
      country: {
        findUnique: vi.fn().mockResolvedValue({ id: "country_de", code: "DE", name: "Germany" }),
      },
      metroCity: {
        findUnique: vi
          .fn()
          .mockResolvedValue({ id: "city_muc", name: "Munich", countryId: "country_de" }),
      },
      holidayCalendar: {
        findMany: vi.fn().mockResolvedValue([]),
      },
    };
    const ctx = createToolContext(holidayCallerDb, [], SystemRole.USER);

    const result = await executeTool(
      "preview_resolved_holiday_calendar",
      JSON.stringify({
        countryId: "country_de",
        stateCode: "BY",
        metroCityId: "city_muc",
        year: 2026,
      }),
      ctx,
    );

    expect(holidayCallerDb.country.findUnique).toHaveBeenCalledWith({
      where: { id: "country_de" },
      select: { id: true, code: true, name: true },
    });
    expect(holidayCallerDb.metroCity.findUnique).toHaveBeenCalledWith({
      where: { id: "city_muc" },
      select: { id: true, name: true, countryId: true },
    });
    expect(JSON.parse(result.content)).toEqual(
      expect.objectContaining({
        count: expect.any(Number),
        locationContext: {
          countryId: "country_de",
          countryCode: "DE",
          stateCode: "BY",
          metroCityId: "city_muc",
          metroCity: "Munich",
          year: 2026,
        },
        summary: expect.objectContaining({
          byCalendar: expect.any(Array),
          byScope: expect.any(Array),
          bySourceType: expect.arrayContaining([
            expect.objectContaining({ sourceType: "BUILTIN" }),
          ]),
        }),
        holidays: expect.arrayContaining([
          expect.objectContaining({
            date: "2026-01-01",
            name: "Neujahr",
            scope: "COUNTRY",
            sourceType: "BUILTIN",
          }),
          expect.objectContaining({
            date: "2026-01-06",
            name: "Heilige Drei Könige",
            scope: "STATE",
            sourceType: "BUILTIN",
          }),
        ]),
      }),
    );
  });
});
