import {
  emitAllocationCreated,
  emitAllocationDeleted,
  emitAllocationUpdated,
} from "../sse/event-bus.js";
import {
  checkBudgetThresholdsInBackground,
  dispatchAllocationWebhookInBackground,
  invalidateDashboardCacheInBackground,
} from "./allocation-effects.js";

type AllocationMutationDb = Parameters<typeof checkBudgetThresholdsInBackground>[0];

type AllocationMutationPayload = {
  id: string;
  projectId: string;
  resourceId: string | null;
};

export function publishAllocationCreated(
  db: AllocationMutationDb,
  payload: AllocationMutationPayload,
  options?: { dispatchWebhook?: boolean },
) {
  emitAllocationCreated(payload);
  if (options?.dispatchWebhook) {
    dispatchAllocationWebhookInBackground(db, "allocation.created", payload);
  }
  invalidateDashboardCacheInBackground();
  checkBudgetThresholdsInBackground(db, payload.projectId);
}

export function publishAllocationUpdated(
  db: AllocationMutationDb,
  payload: AllocationMutationPayload & { resourceIds?: string[] },
  options?: { dispatchWebhook?: boolean },
) {
  emitAllocationUpdated(payload);
  if (options?.dispatchWebhook) {
    dispatchAllocationWebhookInBackground(db, "allocation.updated", payload);
  }
  invalidateDashboardCacheInBackground();
  checkBudgetThresholdsInBackground(db, payload.projectId);
}

export function publishAllocationDeleted(
  db: AllocationMutationDb,
  payload: AllocationMutationPayload,
) {
  emitAllocationDeleted(payload.id, payload.projectId, payload.resourceId);
  invalidateDashboardCacheInBackground();
  checkBudgetThresholdsInBackground(db, payload.projectId);
}

export function publishBatchAllocationDeletes(
  db: AllocationMutationDb,
  payloads: AllocationMutationPayload[],
) {
  for (const payload of payloads) {
    emitAllocationDeleted(payload.id, payload.projectId, payload.resourceId);
  }
  invalidateDashboardCacheInBackground();
  for (const projectId of new Set(payloads.map((payload) => payload.projectId))) {
    checkBudgetThresholdsInBackground(db, projectId);
  }
}

export function publishBatchAllocationStatusUpdates(
  db: AllocationMutationDb,
  payloads: AllocationMutationPayload[],
) {
  for (const payload of payloads) {
    emitAllocationUpdated(payload);
  }
  invalidateDashboardCacheInBackground();
  for (const projectId of new Set(payloads.map((payload) => payload.projectId))) {
    checkBudgetThresholdsInBackground(db, projectId);
  }
}
