import {
  buildSplitAllocationReadModel,
  createAssignment,
} from "@capakraken/application";
import type { PrismaClient } from "@capakraken/db";
import { emitAllocationCreated } from "../sse/event-bus.js";
import {
  assertTimelineDateRangeValid,
  validateTimelineAllocationDateRanges,
} from "./timeline-allocation-mutation-support.js";
import { buildTimelineQuickAssignAssignmentInput } from "./timeline-allocation-quick-assign-support.js";

export async function createTimelineQuickAssignment(
  db: PrismaClient,
  input: Parameters<typeof buildTimelineQuickAssignAssignmentInput>[0],
) {
  assertTimelineDateRangeValid(input.startDate, input.endDate);

  const allocation = await db.$transaction(async (tx) => {
    const assignment = await createAssignment(
      tx as unknown as Parameters<typeof createAssignment>[0],
      buildTimelineQuickAssignAssignmentInput(input),
    );

    return buildSplitAllocationReadModel({
      demandRequirements: [],
      assignments: [assignment],
    }).allocations[0]!;
  });

  emitAllocationCreated({
    id: allocation.id,
    projectId: allocation.projectId,
    resourceId: allocation.resourceId,
  });

  return allocation;
}

export async function createTimelineBatchQuickAssignments(
  db: PrismaClient,
  input: {
    assignments: Array<Parameters<typeof buildTimelineQuickAssignAssignmentInput>[0]>;
  },
) {
  validateTimelineAllocationDateRanges(input.assignments);

  const results = await db.$transaction(async (tx) => {
    const created = [];
    for (const assignment of input.assignments) {
      const createdAssignment = await createAssignment(
        tx as unknown as Parameters<typeof createAssignment>[0],
        buildTimelineQuickAssignAssignmentInput(assignment),
      );
      created.push(createdAssignment);
    }
    return created;
  });

  for (const assignment of results) {
    emitAllocationCreated({
      id: assignment.id,
      projectId: assignment.projectId,
      resourceId: assignment.resourceId,
    });
  }

  return { count: results.length };
}
