import type { Transaction } from "../generated/kysely-tailordb";
import {
  CostCenterNotFoundError,
  CostCenterHasPostingsError,
  CostCenterHasBudgetItemsError,
  CostCenterHasAllocationRulesError,
} from "../lib/errors.generated";
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";

export interface DeleteCostCenterInput {
  costCenterId: string;
}

export async function run(db: Transaction, input: DeleteCostCenterInput, ctx: CommandContext) {
  void ctx;

  // Validate cost center exists
  const costCenter = await db
    .selectFrom("CostCenter")
    .where("id", "=", input.costCenterId)
    .selectAll()
    .forUpdate()
    .executeTakeFirst();

  if (!costCenter) {
    return err(new CostCenterNotFoundError(input.costCenterId));
  }

  // Check for associated cost postings (AllocationResult referencing this cost center)
  const posting = await db
    .selectFrom("AllocationResult")
    .where("senderCostCenterId", "=", input.costCenterId)
    .selectAll()
    .executeTakeFirst();

  if (posting) {
    return err(new CostCenterHasPostingsError(input.costCenterId));
  }

  // Check for associated budget line items via budget
  const budget = await db
    .selectFrom("Budget")
    .where("costObjectType", "=", "CostCenter")
    .where("costObjectId", "=", input.costCenterId)
    .selectAll()
    .executeTakeFirst();

  if (budget) {
    return err(new CostCenterHasBudgetItemsError(input.costCenterId));
  }

  // Check for associated allocation rules
  const allocationRule = await db
    .selectFrom("AllocationRule")
    .where("senderCostCenterId", "=", input.costCenterId)
    .selectAll()
    .executeTakeFirst();

  if (allocationRule) {
    return err(new CostCenterHasAllocationRulesError(input.costCenterId));
  }

  // Delete the cost center
  await db.deleteFrom("CostCenter").where("id", "=", input.costCenterId).execute();

  return ok({ costCenterId: input.costCenterId });
}
