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

export interface ReleaseReservationInput {
  itemId: string;
  storageLocationId: string;
  quantity: number;
}

/**
 * Function: releaseReservation
 *
 * Releases a previously reserved quantity of stock, restoring it
 * to available status. Used when a reservation is no longer needed.
 */
export async function run(db: Transaction, input: ReleaseReservationInput, _ctx: CommandContext) {
  const { itemId, storageLocationId, quantity } = input;

  // 1. Find stock level for item-location pair (forUpdate for write)
  const stockLevel = await db
    .selectFrom("StockLevel")
    .selectAll()
    .where("itemId", "=", itemId)
    .where("storageLocationId", "=", storageLocationId)
    .forUpdate()
    .executeTakeFirst();

  if (!stockLevel) {
    return err(new StockLevelNotFoundError(`${itemId}:${storageLocationId}`));
  }

  // 2. Check reserved >= release amount
  if (stockLevel.reserved < quantity) {
    return err(new InsufficientReservedStockError(`${itemId}:${storageLocationId}`));
  }

  // 3. Decrement reserved quantity
  const updatedStockLevel = await db
    .updateTable("StockLevel")
    .set({
      reserved: stockLevel.reserved - quantity,
      updatedAt: new Date(),
    })
    .where("id", "=", stockLevel.id)
    .returningAll()
    .executeTakeFirst();

  return ok({ stockLevel: updatedStockLevel! });
}
