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

export interface CreateSalesPriceRuleInput {
  salesPriceListId: string;
  itemId: string;
  customerId?: string | null;
  channelId?: string | null;
  currencyId: string;
  unitId: string;
  minimumQuantity?: number;
  unitPrice: number;
  effectiveFrom?: Date | null;
  effectiveTo?: Date | null;
  priority?: number;
  notes?: string;
}

export async function run(db: Transaction, input: CreateSalesPriceRuleInput, ctx: CommandContext) {
  void ctx;
  const salesPriceList = await db
    .selectFrom("SalesPriceList")
    .selectAll()
    .where("id", "=", input.salesPriceListId)
    .executeTakeFirst();
  if (!salesPriceList) {
    return err(new PriceListNotFoundError(input.salesPriceListId));
  }
  if (!input.itemId || !input.currencyId || !input.unitId) {
    return err(new IdentifierRequiredError("sales-price-rule.scope"));
  }
  if (input.unitPrice <= 0 || (input.minimumQuantity ?? 0) < 0) {
    return err(new InvalidUnitPriceError(input.itemId));
  }
  if (input.effectiveFrom && input.effectiveTo && input.effectiveTo < input.effectiveFrom) {
    return err(new InvalidEffectiveRangeError(input.itemId));
  }
  const salesPriceRule = await db
    .insertInto("SalesPriceRule")
    .values({
      salesPriceListId: input.salesPriceListId,
      itemId: input.itemId,
      customerId: input.customerId ?? null,
      channelId: input.channelId ?? null,
      currencyId: input.currencyId,
      unitId: input.unitId,
      minimumQuantity: input.minimumQuantity ?? 0,
      unitPrice: input.unitPrice,
      effectiveFrom: input.effectiveFrom ?? null,
      effectiveTo: input.effectiveTo ?? null,
      priority: input.priority ?? 0,
      status: "DRAFT",
      notes: input.notes ?? null,
      createdAt: new Date(),
      updatedAt: null,
    })
    .returningAll()
    .executeTakeFirst();
  return ok({ salesPriceRule: salesPriceRule! });
}
