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<typeof formatTimelineHolidayOverlays>,
) {
  const resourceIds = new Set<string>();
  const byScope = new Map<string, number>();

  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<string | null>;
  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<string, unknown>;
  overlays: ReturnType<typeof formatTimelineHolidayOverlays>;
}) {
  return {
    period: {
      startDate: fmtDate(input.startDate),
      endDate: fmtDate(input.endDate),
    },
    filters: input.filters,
    summary: summarizeTimelineHolidayOverlays(input.overlays),
    overlays: input.overlays,
  };
}
