import { getAnonymizationDirectory } from "../lib/anonymization.js";
import {
  buildSelfServiceTimelineInput,
  buildTimelineEntriesDetailInput,
  createEmptyTimelineEntriesView,
  loadTimelineEntriesReadModel,
} from "./timeline-read-shared.js";
import {
  buildTimelineEntriesDetailResponse,
  buildTimelineEntriesViewResponse,
} from "./timeline-entry-response-support.js";
import {
  formatHolidayOverlays,
  loadTimelineHolidayOverlaysForReadModel,
  summarizeHolidayOverlays,
} from "./timeline-holiday-read.js";

type TimelineEntryProcedureDb =
  & Parameters<typeof getAnonymizationDirectory>[0]
  & Parameters<typeof loadTimelineEntriesReadModel>[0]
  & Parameters<typeof loadTimelineHolidayOverlaysForReadModel>[0];
type TimelineEntrySelfServiceContext = Parameters<typeof buildSelfServiceTimelineInput>[0];
type TimelineEntryViewInput = Parameters<typeof loadTimelineEntriesReadModel>[1];
type TimelineEntryDetailInput = Parameters<typeof buildTimelineEntriesDetailInput>[0];

async function loadTimelineEntriesViewResponse(
  db: TimelineEntryProcedureDb,
  input: TimelineEntryViewInput,
) {
  const [readModel, directory] = await Promise.all([
    loadTimelineEntriesReadModel(db, input),
    getAnonymizationDirectory(db),
  ]);

  return buildTimelineEntriesViewResponse(readModel, directory);
}

export async function readTimelineEntries(
  db: TimelineEntryProcedureDb,
  input: TimelineEntryViewInput,
) {
  return (await loadTimelineEntriesViewResponse(db, input)).allocations;
}

export async function readTimelineEntriesView(
  db: TimelineEntryProcedureDb,
  input: TimelineEntryViewInput,
) {
  return loadTimelineEntriesViewResponse(db, input);
}

export async function readMyTimelineEntriesView(
  ctx: TimelineEntrySelfServiceContext,
  input: TimelineEntryViewInput,
) {
  const selfServiceInput = await buildSelfServiceTimelineInput(ctx, input);
  if (!selfServiceInput) {
    return createEmptyTimelineEntriesView();
  }

  return readTimelineEntriesView(ctx.db, selfServiceInput);
}

export async function readTimelineEntriesDetail(
  db: TimelineEntryProcedureDb,
  input: TimelineEntryDetailInput,
) {
  const { period, filters, timelineInput } = buildTimelineEntriesDetailInput(input);
  const [readModel, directory] = await Promise.all([
    loadTimelineEntriesReadModel(db, timelineInput),
    getAnonymizationDirectory(db),
  ]);
  const holidayOverlays = await loadTimelineHolidayOverlaysForReadModel(
    db,
    timelineInput,
    readModel,
  );
  const formattedHolidayOverlays = formatHolidayOverlays(holidayOverlays);

  return buildTimelineEntriesDetailResponse({
    period,
    filters,
    readModel,
    directory,
    holidayOverlays: formattedHolidayOverlays,
    holidaySummary: summarizeHolidayOverlays(formattedHolidayOverlays),
  });
}
