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

export interface CompleteInventoryCountInput {
  inventoryCountId: string;
}

/**
 * Function: completeInventoryCount
 *
 * Completes the inventory count, transitioning from IN_PROGRESS to COMPLETED.
 * All count lines must be in a terminal status (APPROVED or REJECTED).
 * Unfreezes stock if it was frozen during the count.
 */
export async function run(
  db: Transaction,
  input: CompleteInventoryCountInput,
  _ctx: CommandContext,
) {
  const { inventoryCountId } = input;

  // 1. Fetch count
  const count = await db
    .selectFrom("InventoryCount")
    .selectAll()
    .where("id", "=", inventoryCountId)
    .forUpdate()
    .executeTakeFirst();

  if (!count) {
    return err(new CountNotFoundError(inventoryCountId));
  }

  // 2. Validate status
  if (count.status !== "IN_PROGRESS") {
    return err(new CountNotInProgressError(inventoryCountId));
  }

  // 3. Check all lines are in terminal status
  const lines = await db
    .selectFrom("InventoryCountLine")
    .selectAll()
    .where("inventoryCountId", "=", inventoryCountId)
    .execute();

  const unresolvedLines = lines.filter((l) => l.status !== "APPROVED" && l.status !== "REJECTED");

  if (unresolvedLines.length > 0) {
    return err(new UnresolvedCountLinesError(inventoryCountId));
  }

  // 4. Update status to COMPLETED and unfreeze if frozen
  const updatedCount = await db
    .updateTable("InventoryCount")
    .set({
      status: "COMPLETED",
      isFrozen: false,
      updatedAt: new Date(),
    })
    .where("id", "=", inventoryCountId)
    .returningAll()
    .executeTakeFirst();

  return ok({ inventoryCount: updatedCount! });
}
