import { VacationStatus, VacationType } from "@capakraken/db";
import { asHolidayResolverDb, getResolvedCalendarHolidays } from "../lib/holiday-availability.js";
import type { TRPCContext } from "../trpc.js";

type VacationDb = TRPCContext["db"];

export type BatchCreatePublicHolidaysInput = {
  year: number;
  federalState?: string | undefined;
  chapter?: string | undefined;
  replaceExisting: boolean;
};

export async function batchCreatePublicHolidayVacations(
  db: VacationDb,
  input: BatchCreatePublicHolidaysInput,
  adminUserId: string,
): Promise<{ created: number; holidays: number; resources: number }> {
  const resources = await db.resource.findMany({
    where: {
      isActive: true,
      ...(input.chapter ? { chapter: input.chapter } : {}),
    },
    select: {
      id: true,
      federalState: true,
      countryId: true,
      metroCityId: true,
      country: { select: { code: true } },
      metroCity: { select: { name: true } },
    },
  });

  if (resources.length === 0) {
    return { created: 0, holidays: 0, resources: 0 };
  }

  let created = 0;
  let holidayCount = 0;

  for (const resource of resources) {
    const holidays = await getResolvedCalendarHolidays(asHolidayResolverDb(db), {
      periodStart: new Date(`${input.year}-01-01T00:00:00.000Z`),
      periodEnd: new Date(`${input.year}-12-31T00:00:00.000Z`),
      countryId: resource.countryId,
      countryCode: resource.country?.code,
      federalState: input.federalState ?? resource.federalState,
      metroCityId: resource.metroCityId,
      metroCityName: resource.metroCity?.name,
    });
    holidayCount += holidays.length;

    for (const holiday of holidays) {
      const startDate = new Date(holiday.date);
      const endDate = new Date(holiday.date);

      if (input.replaceExisting) {
        await db.vacation.deleteMany({
          where: {
            resourceId: resource.id,
            type: VacationType.PUBLIC_HOLIDAY,
            startDate,
            endDate,
          },
        });
      }

      const exists = await db.vacation.findFirst({
        where: {
          resourceId: resource.id,
          type: VacationType.PUBLIC_HOLIDAY,
          startDate,
          endDate,
        },
      });
      if (exists) {
        continue;
      }

      await db.vacation.create({
        data: {
          resourceId: resource.id,
          type: VacationType.PUBLIC_HOLIDAY,
          status: VacationStatus.APPROVED,
          startDate,
          endDate,
          note: holiday.name,
          requestedById: adminUserId,
          approvedById: adminUserId,
          approvedAt: new Date(),
        },
      });
      created++;
    }
  }

  return { created, holidays: holidayCount, resources: resources.length };
}
