import { err, ok, type CommandContext } from "@tailor-platform/erp-kit/core";
import type { Transaction } from "../generated/kysely-tailordb";
import {
  ImmutableOwnerChangeError,
  InvalidListPriorityError,
  PriceListNotFoundError,
} from "../lib/errors.generated";

export type UpdatePurchasePriceListInput = {
  id: string;
  companyId?: string;
  supplierId?: string;
  name?: string;
  code?: string;
  priority?: number;
  notes?: string | null;
};
export async function run<CF extends Record<string, unknown>>(
  db: Transaction,
  input: UpdatePurchasePriceListInput & Partial<CF>,
  _ctx: CommandContext,
) {
  const {
    id,
    companyId: inputCompanyId,
    supplierId: inputSupplierId,
    name,
    code,
    priority,
    notes,
    ...customFields
  } = input;
  const existing = await db
    .selectFrom("PurchasePriceList")
    .selectAll()
    .where("id", "=", id)
    .forUpdate()
    .executeTakeFirst();
  if (!existing) {
    return err(new PriceListNotFoundError(id));
  }

  if (
    (inputCompanyId && inputCompanyId !== existing.companyId) ||
    (inputSupplierId && inputSupplierId !== existing.supplierId)
  ) {
    return err(new ImmutableOwnerChangeError(id));
  }
  if (priority !== undefined && priority < 0) {
    return err(new InvalidListPriorityError(String(priority)));
  }

  const purchasePriceList = await db
    .updateTable("PurchasePriceList")
    .set({
      ...(customFields as Record<string, unknown>),
      name: name ?? existing.name,
      code: code ?? existing.code,
      priority: priority ?? existing.priority,
      notes: notes === undefined ? existing.notes : notes,
      updatedAt: new Date(),
    })
    .where("id", "=", id)
    .returningAll()
    .executeTakeFirstOrThrow();

  return ok({ purchasePriceList });
}
