import { listAssignmentBookings } from "@capakraken/application";
import { loadProjectPlanningReadModel } from "./project-planning-read-model.js";
import {
  findTimelineProjectOrThrow,
  projectShiftContextSelect,
  timelineProjectContextSelect,
} from "./timeline-project-query-support.js";
import { buildTimelineShiftPlan } from "./timeline-shift-planning.js";
import { getAssignmentResourceIds, ShiftDbClient } from "./timeline-read-shared.js";
import { buildTimelineProjectShiftValidation } from "./timeline-shift-support.js";
import { buildTimelineShiftValidationBookings } from "./timeline-project-read-support.js";

export async function loadProjectShiftContext(db: ShiftDbClient, projectId: string) {
  const [project, planningRead] = await Promise.all([
    findTimelineProjectOrThrow(db, {
      projectId,
      select: projectShiftContextSelect,
    }),
    loadProjectPlanningReadModel(db, { projectId, activeOnly: true }),
  ]);

  const { demandRequirements, assignments, readModel: projectReadModel } = planningRead;

  const resourceIds = getAssignmentResourceIds(projectReadModel);
  const allAssignmentWindows =
    resourceIds.length === 0
      ? []
      : buildTimelineShiftValidationBookings(
          await listAssignmentBookings(db, {
            resourceIds,
          }),
        );

  const shiftPlan = buildTimelineShiftPlan({
    demandRequirements,
    assignments,
    allAssignmentWindows,
  });

  return {
    project,
    demandRequirements,
    assignments,
    shiftPlan,
  };
}

export async function loadTimelineProjectContext(db: ShiftDbClient, projectId: string) {
  const [project, planningRead] = await Promise.all([
    findTimelineProjectOrThrow(db, {
      projectId,
      select: timelineProjectContextSelect,
    }),
    loadProjectPlanningReadModel(db, {
      projectId,
      activeOnly: true,
    }),
  ]);

  const resourceIds = getAssignmentResourceIds(planningRead.readModel);
  const allResourceAllocations =
    resourceIds.length === 0
      ? []
      : await listAssignmentBookings(db, {
          resourceIds,
        });

  return {
    project,
    allocations: planningRead.readModel.allocations,
    demands: planningRead.readModel.demands,
    assignments: planningRead.readModel.assignments,
    allResourceAllocations,
    resourceIds,
  };
}

export async function previewTimelineProjectShift(
  db: ShiftDbClient,
  input: {
    projectId: string;
    newStartDate: Date;
    newEndDate: Date;
  },
) {
  const context = await loadProjectShiftContext(db, input.projectId);

  return buildTimelineProjectShiftValidation({
    context,
    newStartDate: input.newStartDate,
    newEndDate: input.newEndDate,
  });
}
