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

export interface ApproveCountLineInput {
  countLineId: string;
}

/**
 * Function: approveCountLine
 *
 * Approves a count line variance, transitioning it from PENDING to APPROVED.
 * When variance is non-zero, generates an inventory adjustment with reason "inventory-count".
 */
export async function run(db: Transaction, input: ApproveCountLineInput, _ctx: CommandContext) {
  const { countLineId } = input;

  // 1. Fetch count line
  const countLine = await db
    .selectFrom("InventoryCountLine")
    .selectAll()
    .where("id", "=", countLineId)
    .forUpdate()
    .executeTakeFirst();

  if (!countLine) {
    return err(new CountLineNotFoundError(countLineId));
  }

  // 2. Validate status
  if (countLine.status !== "PENDING") {
    return err(new CountLineNotPendingError(countLineId));
  }

  // 3. Approve the line
  const updatedLine = await db
    .updateTable("InventoryCountLine")
    .set({
      status: "APPROVED",
      updatedAt: new Date(),
    })
    .where("id", "=", countLineId)
    .returningAll()
    .executeTakeFirst();

  // 4. Generate adjustment if variance is non-zero
  if (countLine.variance !== 0 && countLine.variance !== null) {
    await db
      .insertInto("InventoryAdjustment")
      .values({
        adjustmentType: "CORRECTION",
        itemId: countLine.itemId,
        storageLocationId: countLine.storageLocationId,
        quantityDelta: countLine.variance,
        reasonCode: "inventory-count",
        status: "APPROVED",
        inventoryCountId: countLine.inventoryCountId,
        lotId: null,
        serialNumberId: null,
        createdAt: new Date(),
        updatedAt: null,
      })
      .returningAll()
      .executeTakeFirst();
  }

  return ok({ countLine: updatedLine! });
}
