import type { PrismaClient, Prisma } from "@capakraken/db";
import { type UpdateDemandRequirementInput } from "@capakraken/shared";
import { TRPCError } from "@trpc/server";
import {
  DEMAND_REQUIREMENT_RELATIONS_INCLUDE,
  type DemandRequirementWithRelations,
} from "./create-demand-requirement.js";

type DbClient = PrismaClient | Prisma.TransactionClient;

export async function updateDemandRequirement(
  db: DbClient,
  id: string,
  input: UpdateDemandRequirementInput,
): Promise<DemandRequirementWithRelations> {
  const existing = await db.demandRequirement.findUnique({
    where: { id },
    include: DEMAND_REQUIREMENT_RELATIONS_INCLUDE,
  });

  if (!existing) {
    throw new TRPCError({ code: "NOT_FOUND", message: "Demand requirement not found" });
  }

  const updatedDemandRequirement = await db.demandRequirement.update({
    where: { id },
    data: {
      ...(input.projectId !== undefined ? { projectId: input.projectId } : {}),
      ...(input.startDate !== undefined ? { startDate: input.startDate } : {}),
      ...(input.endDate !== undefined ? { endDate: input.endDate } : {}),
      ...(input.hoursPerDay !== undefined ? { hoursPerDay: input.hoursPerDay } : {}),
      ...(input.percentage !== undefined ? { percentage: input.percentage } : {}),
      ...(input.role !== undefined ? { role: input.role } : {}),
      ...(input.roleId !== undefined ? { roleId: input.roleId } : {}),
      ...(input.headcount !== undefined ? { headcount: input.headcount } : {}),
      ...(input.budgetCents !== undefined ? { budgetCents: input.budgetCents } : {}),
      ...(input.status !== undefined ? { status: input.status } : {}),
      ...(input.metadata !== undefined
        ? { metadata: input.metadata as unknown as Prisma.InputJsonValue }
        : {}),
    },
    include: DEMAND_REQUIREMENT_RELATIONS_INCLUDE,
  });

  await db.auditLog.create({
    data: {
      entityType: "DemandRequirement",
      entityId: id,
      action: "UPDATE",
      changes: {
        before: {
          projectId: existing.projectId,
          startDate: existing.startDate,
          endDate: existing.endDate,
          hoursPerDay: existing.hoursPerDay,
          percentage: existing.percentage,
          role: existing.role,
          roleId: existing.roleId,
          headcount: existing.headcount,
          status: existing.status,
        },
        after: {
          projectId: updatedDemandRequirement.projectId,
          startDate: updatedDemandRequirement.startDate,
          endDate: updatedDemandRequirement.endDate,
          hoursPerDay: updatedDemandRequirement.hoursPerDay,
          percentage: updatedDemandRequirement.percentage,
          role: updatedDemandRequirement.role,
          roleId: updatedDemandRequirement.roleId,
          headcount: updatedDemandRequirement.headcount,
          status: updatedDemandRequirement.status,
        },
      } as unknown as Prisma.InputJsonValue,
    },
  });

  return updatedDemandRequirement;
}
