import { TRPCError } from "@trpc/server";
import { createAuditEntry } from "../lib/audit.js";
import type { ScenarioChangeInput, ScenarioDb } from "./scenario-shared.js";

export async function applyProjectScenario(
  db: ScenarioDb,
  input: {
    projectId: string;
    changes: ScenarioChangeInput[];
    userId?: string;
  },
) {
  const { projectId, changes, userId } = input;

  const project = await db.project.findUnique({
    where: { id: projectId },
    select: { id: true, name: true },
  });
  if (!project) {
    throw new TRPCError({ code: "NOT_FOUND", message: "Project not found" });
  }

  const created: string[] = [];

  for (const change of changes) {
    if (change.remove && change.assignmentId) {
      await db.assignment.update({
        where: { id: change.assignmentId },
        data: { status: "CANCELLED" },
      });
      continue;
    }

    if (change.assignmentId) {
      await db.assignment.update({
        where: { id: change.assignmentId },
        data: {
          startDate: change.startDate,
          endDate: change.endDate,
          hoursPerDay: change.hoursPerDay,
          ...(change.resourceId ? { resourceId: change.resourceId } : {}),
          ...(change.roleId ? { roleId: change.roleId } : {}),
        },
      });
      created.push(change.assignmentId);
      continue;
    }

    if (!change.resourceId) {
      continue;
    }

    const resource = await db.resource.findUnique({
      where: { id: change.resourceId },
      select: { lcrCents: true },
    });
    const dailyCostCents = Math.round((resource?.lcrCents ?? 0) * change.hoursPerDay);

    const newAssignment = await db.assignment.create({
      data: {
        projectId,
        resourceId: change.resourceId,
        ...(change.roleId ? { roleId: change.roleId } : {}),
        startDate: change.startDate,
        endDate: change.endDate,
        hoursPerDay: change.hoursPerDay,
        percentage: 100,
        dailyCostCents,
        status: "PROPOSED",
        metadata: {},
      },
    });
    created.push(newAssignment.id);
  }

  void createAuditEntry({
    db,
    entityType: "ScenarioApplication",
    entityId: projectId,
    entityName: project.name,
    action: "CREATE",
    ...(userId ? { userId } : {}),
    summary: `Applied scenario to project "${project.name}" (${created.length} allocations created/modified)`,
    metadata: { appliedCount: created.length, assignmentIds: created },
    source: "ui",
  });

  return { appliedCount: created.length };
}
