import type { Prisma } from "@capakraken/db"; import { fmtDate } from "./timeline-read-shared.js"; export interface TimelineHolidayOverlayRecord { id: string; resourceId: string; startDate: Date; endDate: Date; note?: string | null; scope?: string | null; calendarName?: string | null; sourceType?: string | null; countryCode?: string | null; countryName?: string | null; federalState?: string | null; metroCityName?: string | null; } export function formatTimelineHolidayOverlays(overlays: TimelineHolidayOverlayRecord[]) { return overlays.map((overlay) => ({ id: overlay.id, resourceId: overlay.resourceId, startDate: fmtDate(overlay.startDate), endDate: fmtDate(overlay.endDate), note: overlay.note ?? null, scope: overlay.scope ?? null, calendarName: overlay.calendarName ?? null, sourceType: overlay.sourceType ?? null, countryCode: overlay.countryCode ?? null, countryName: overlay.countryName ?? null, federalState: overlay.federalState ?? null, metroCityName: overlay.metroCityName ?? null, })); } export function summarizeTimelineHolidayOverlays( overlays: ReturnType, ) { const resourceIds = new Set(); const byScope = new Map(); for (const overlay of overlays) { resourceIds.add(overlay.resourceId); const scope = overlay.scope ?? "UNKNOWN"; byScope.set(scope, (byScope.get(scope) ?? 0) + 1); } return { overlayCount: overlays.length, holidayResourceCount: resourceIds.size, byScope: [...byScope.entries()] .sort(([left], [right]) => left.localeCompare(right)) .map(([scope, count]) => ({ scope, count })), }; } export function buildTimelineHolidayResourceWhere(input: { chapters?: string[] | undefined; eids?: string[] | undefined; countryCodes?: string[] | undefined; }): Prisma.ResourceWhereInput | null { const andConditions: Prisma.ResourceWhereInput[] = []; if (input.chapters && input.chapters.length > 0) { andConditions.push({ chapter: { in: input.chapters } }); } if (input.eids && input.eids.length > 0) { andConditions.push({ eid: { in: input.eids } }); } if (input.countryCodes && input.countryCodes.length > 0) { andConditions.push({ country: { code: { in: input.countryCodes } } }); } if (andConditions.length === 0) { return null; } return andConditions.length === 1 ? andConditions[0]! : { AND: andConditions }; } export function buildTimelineHolidayResourceIds(input: { assignmentResourceIds: Array; requestedResourceIds?: string[] | undefined; matchingFilterResourceIds?: string[] | undefined; }) { const resourceIds = new Set( input.assignmentResourceIds.filter( (resourceId): resourceId is string => typeof resourceId === "string" && resourceId.length > 0, ), ); for (const resourceId of input.requestedResourceIds ?? []) { if (resourceId) { resourceIds.add(resourceId); } } for (const resourceId of input.matchingFilterResourceIds ?? []) { if (resourceId) { resourceIds.add(resourceId); } } return [...resourceIds]; } export function buildTimelineHolidayOverlayDetailResponse(input: { startDate: Date; endDate: Date; filters: Record; overlays: ReturnType; }) { return { period: { startDate: fmtDate(input.startDate), endDate: fmtDate(input.endDate), }, filters: input.filters, summary: summarizeTimelineHolidayOverlays(input.overlays), overlays: input.overlays, }; }