import type { PrismaClient } from "@capakraken/db";

type DbClient = Pick<PrismaClient, "vacation" | "vacationEntitlement" | "systemSettings" | "resource">;

export type SetEntitlementInput = {
  resourceId: string;
  year: number;
  entitledDays: number;
};

export type BulkSetEntitlementsInput = {
  year: number;
  entitledDays: number;
  resourceIds?: string[] | undefined;
};

export type SetEntitlementResult = Awaited<ReturnType<PrismaClient["vacationEntitlement"]["update"]>>;
export type CreateEntitlementResult = Awaited<ReturnType<PrismaClient["vacationEntitlement"]["create"]>>;

export type SetEntitlementReturn = {
  result: SetEntitlementResult | CreateEntitlementResult;
  existing: SetEntitlementResult | null;
};

export async function setEntitlement(
  db: DbClient,
  input: SetEntitlementInput,
): Promise<SetEntitlementReturn> {
  const existing = await db.vacationEntitlement.findUnique({
    where: { resourceId_year: { resourceId: input.resourceId, year: input.year } },
  });

  if (existing) {
    const updated = await db.vacationEntitlement.update({
      where: { id: existing.id },
      data: { entitledDays: input.entitledDays },
    });
    return { result: updated, existing };
  }

  const created = await db.vacationEntitlement.create({
    data: {
      resourceId: input.resourceId,
      year: input.year,
      entitledDays: input.entitledDays,
      carryoverDays: 0,
      usedDays: 0,
      pendingDays: 0,
    },
  });

  return { result: created, existing: null };
}

export type BulkSetEntitlementsResult = {
  updated: number;
};

export async function bulkSetEntitlements(
  db: DbClient,
  input: BulkSetEntitlementsInput,
): Promise<BulkSetEntitlementsResult> {
  const resources = await db.resource.findMany({
    where: {
      isActive: true,
      ...(input.resourceIds ? { id: { in: input.resourceIds } } : {}),
    },
    select: { id: true },
  });

  let updated = 0;
  for (const resource of resources) {
    await db.vacationEntitlement.upsert({
      where: { resourceId_year: { resourceId: resource.id, year: input.year } },
      create: {
        resourceId: resource.id,
        year: input.year,
        entitledDays: input.entitledDays,
        carryoverDays: 0,
        usedDays: 0,
        pendingDays: 0,
      },
      update: { entitledDays: input.entitledDays },
    });
    updated++;
  }

  return { updated };
}
