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

export const timelineEntryReadProcedures = {
  getEntries: controllerProcedure
    .input(TimelineWindowFiltersSchema)
    .query(async ({ ctx, input }) => {
      const readModel = await loadTimelineEntriesReadModel(ctx.db, input);
      const directory = await getAnonymizationDirectory(ctx.db);
      return buildTimelineEntriesViewResponse(readModel, directory).allocations;
    }),

  getEntriesView: controllerProcedure
    .input(TimelineWindowFiltersSchema)
    .query(async ({ ctx, input }) => {
      const [readModel, directory] = await Promise.all([
        loadTimelineEntriesReadModel(ctx.db, input),
        getAnonymizationDirectory(ctx.db),
      ]);

      return buildTimelineEntriesViewResponse(readModel, directory);
    }),

  getMyEntriesView: protectedProcedure
    .input(TimelineWindowFiltersSchema)
    .query(async ({ ctx, input }) => {
      const selfServiceInput = await buildSelfServiceTimelineInput(ctx, input);
      if (!selfServiceInput) {
        return createEmptyTimelineEntriesView();
      }

      const [readModel, directory] = await Promise.all([
        loadTimelineEntriesReadModel(ctx.db, selfServiceInput),
        getAnonymizationDirectory(ctx.db),
      ]);

      return buildTimelineEntriesViewResponse(readModel, directory);
    }),

  getEntriesDetail: controllerProcedure
    .input(
      z.object({
        startDate: z.string().optional(),
        endDate: z.string().optional(),
        durationDays: z.number().int().min(1).max(366).optional(),
        resourceIds: z.array(z.string()).optional(),
        projectIds: z.array(z.string()).optional(),
        clientIds: z.array(z.string()).optional(),
        chapters: z.array(z.string()).optional(),
        eids: z.array(z.string()).optional(),
        countryCodes: z.array(z.string()).optional(),
      }),
    )
    .query(async ({ ctx, input }) => {
      const { period, filters, timelineInput } = buildTimelineEntriesDetailInput(input);

      const [readModel, directory] = await Promise.all([
        loadTimelineEntriesReadModel(ctx.db, timelineInput),
        getAnonymizationDirectory(ctx.db),
      ]);
      const holidayOverlays = await loadTimelineHolidayOverlaysForReadModel(
        ctx.db,
        timelineInput,
        readModel,
      );
      const formattedHolidayOverlays = formatHolidayOverlays(holidayOverlays);

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