import { listAssignmentBookings } from "@capakraken/application";
import { computeBudgetStatus } from "@capakraken/engine";
import {
  previewTimelineProjectShift,
} from "./timeline-project-load-support.js";
import {
  buildTimelineBudgetStatusAllocations,
  buildTimelineBudgetStatusResponse,
  buildTimelineShiftPreviewDetailResponse,
} from "./timeline-project-read-support.js";
import {
  findTimelineProjectOrThrow,
  timelineBudgetStatusProjectSelect,
  timelineShiftPreviewProjectSelect,
} from "./timeline-project-query-support.js";

type TimelineProjectProcedureDb =
  & Parameters<typeof previewTimelineProjectShift>[0]
  & Parameters<typeof findTimelineProjectOrThrow>[0]
  & Parameters<typeof listAssignmentBookings>[0];

export async function readTimelineProjectShiftPreviewDetail(
  db: TimelineProjectProcedureDb,
  input: {
    projectId: string;
    newStartDate: Date;
    newEndDate: Date;
  },
) {
  const [project, preview] = await Promise.all([
    findTimelineProjectOrThrow(db, {
      projectId: input.projectId,
      select: timelineShiftPreviewProjectSelect,
    }),
    previewTimelineProjectShift(db, input),
  ]);

  return buildTimelineShiftPreviewDetailResponse({
    project,
    requestedShift: {
      newStartDate: input.newStartDate,
      newEndDate: input.newEndDate,
    },
    preview,
  });
}

export async function readTimelineProjectShiftPreview(
  db: TimelineProjectProcedureDb,
  input: {
    projectId: string;
    newStartDate: Date;
    newEndDate: Date;
  },
) {
  return previewTimelineProjectShift(db, input);
}

export async function readTimelineProjectBudgetStatusResponse(
  db: TimelineProjectProcedureDb,
  projectId: string,
) {
  const project = await findTimelineProjectOrThrow(db, {
    projectId,
    select: timelineBudgetStatusProjectSelect,
  });

  const bookings = await listAssignmentBookings(db, {
    projectIds: [project.id],
  });

  const budgetStatus = computeBudgetStatus(
    project.budgetCents,
    project.winProbability,
    buildTimelineBudgetStatusAllocations(bookings),
    project.startDate,
    project.endDate,
  );

  return buildTimelineBudgetStatusResponse({
    project,
    budgetStatus,
    totalAllocations: bookings.length,
  });
}
