import type { Transaction } from "../generated/kysely-tailordb";
import {
  CostElementNotFoundError,
  CostObjectNotFoundError,
  AccountingPeriodNotFoundError,
  InvalidCommitmentAmountError,
  NoActiveBudgetError,
} from "../lib/errors.generated";
import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/module";

export interface RecordCommitmentInput {
  costElementId: string;
  costObjectType: string;
  costObjectId: string;
  accountingPeriodId: string;
  amount: number;
  purchaseOrderId: string;
  companyId: string;
}

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

  // Validate cost element exists
  const costElement = await db
    .selectFrom("CostElement")
    .where("id", "=", input.costElementId)
    .selectAll()
    .executeTakeFirst();

  if (!costElement) {
    return err(new CostElementNotFoundError(input.costElementId));
  }

  // Validate cost object exists (polymorphic: CostCenter, ProfitCenter, or InternalOrder)
  let costObject: unknown;
  if (input.costObjectType === "CostCenter") {
    costObject = await db
      .selectFrom("CostCenter")
      .where("id", "=", input.costObjectId)
      .selectAll()
      .executeTakeFirst();
  } else if (input.costObjectType === "ProfitCenter") {
    costObject = await db
      .selectFrom("ProfitCenter")
      .where("id", "=", input.costObjectId)
      .selectAll()
      .executeTakeFirst();
  } else if (input.costObjectType === "InternalOrder") {
    costObject = await db
      .selectFrom("InternalOrder")
      .where("id", "=", input.costObjectId)
      .selectAll()
      .executeTakeFirst();
  }

  if (!costObject) {
    return err(new CostObjectNotFoundError(input.costObjectId));
  }

  // Validate accounting period exists
  const accountingPeriod = await db
    .selectFrom("AccountingPeriod" as never)
    .where("id" as never, "=", input.accountingPeriodId as never)
    .selectAll()
    .executeTakeFirst();

  if (!accountingPeriod) {
    return err(new AccountingPeriodNotFoundError(input.accountingPeriodId));
  }

  // Validate positive amount
  if (input.amount <= 0) {
    return err(new InvalidCommitmentAmountError(String(input.amount)));
  }

  // Validate active budget exists for the cost object
  const activeBudget = await db
    .selectFrom("Budget")
    .where("costObjectId", "=", input.costObjectId)
    .where("costObjectType", "=", input.costObjectType)
    .where("status", "=", "ACTIVE")
    .selectAll()
    .executeTakeFirst();

  if (!activeBudget) {
    return err(new NoActiveBudgetError(input.costObjectId));
  }

  // Budget availability is calculated dynamically (Budget - Actual - Commitments - Encumbrances)
  // Creating this commitment automatically reduces future budget availability calculations

  // Create commitment with status OPEN and consumedAmount 0
  const commitment = await db
    .insertInto("Commitment")
    .values({
      costElementId: input.costElementId,
      costObjectType: input.costObjectType,
      costObjectId: input.costObjectId,
      accountingPeriodId: input.accountingPeriodId,
      amount: input.amount,
      consumedAmount: 0,
      purchaseOrderId: input.purchaseOrderId,
      companyId: input.companyId,
      status: "OPEN",
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirst();

  return ok({ commitment: commitment! });
}
