import type { SplitAssignmentRecord } from "@capakraken/application";
import { Prisma, type PrismaClient } from "@capakraken/db";
import type { ShiftValidationResult, WeekdayAvailability } from "@capakraken/shared";
import { calculateTimelineAllocationDailyCost } from "./timeline-cost-support.js";
import type { TimelineShiftProjectRecord } from "./timeline-shift-support.js";

export function buildTimelineProjectDateRangeUpdate(input: {
  newStartDate: Date;
  newEndDate: Date;
}) {
  return {
    startDate: input.newStartDate,
    endDate: input.newEndDate,
  };
}

export function buildTimelineShiftedAssignmentUpdate(input: {
  newStartDate: Date;
  newEndDate: Date;
  dailyCostCents: number | undefined;
}) {
  return {
    ...buildTimelineProjectDateRangeUpdate(input),
    ...(input.dailyCostCents !== undefined ? { dailyCostCents: input.dailyCostCents } : {}),
  };
}

export function buildTimelineProjectShiftAuditChanges(input: {
  project: TimelineShiftProjectRecord;
  newStartDate: Date;
  newEndDate: Date;
  validation: ShiftValidationResult;
}): Prisma.InputJsonValue {
  return {
    before: {
      startDate: input.project.startDate,
      endDate: input.project.endDate,
    },
    after: {
      startDate: input.newStartDate,
      endDate: input.newEndDate,
    },
    costImpact: input.validation.costImpact,
  } as unknown as Prisma.InputJsonValue;
}

export async function recalculateShiftedAssignmentDailyCost(input: {
  db: PrismaClient;
  assignment: SplitAssignmentRecord;
  newStartDate: Date;
  newEndDate: Date;
}): Promise<number | undefined> {
  if (!input.assignment.resourceId || !input.assignment.resource) {
    return undefined;
  }

  const metadata = (input.assignment.metadata as Record<string, unknown> | null | undefined) ?? {};
  const includeSaturday = (metadata.includeSaturday as boolean | undefined) ?? false;

  return calculateTimelineAllocationDailyCost({
    db: input.db,
    resourceId: input.assignment.resourceId,
    lcrCents: input.assignment.resource.lcrCents,
    hoursPerDay: input.assignment.hoursPerDay,
    startDate: input.newStartDate,
    endDate: input.newEndDate,
    availability: input.assignment.resource.availability as WeekdayAvailability,
    includeSaturday,
  });
}
