// Generated by bynkc — do not edit by hand.
// commons commerce.identifiers

import { Ok, Err, Some, None, type Result, type Option, type ValidationError } from "./runtime.js";

export type Sku = string & { readonly __brand: "Sku" };

export const Sku = {
  of(value: string): Result<Sku, ValidationError> {
    if (!new RegExp("^" + "[A-Z0-9]{3,16}" + "$").test(value)) {
      return Err({ field: "Sku", message: "must match /[A-Z0-9]{3,16}/", value });
    }
    return Ok(value as Sku);
  },
  unsafe(value: string): Sku {
    return value as Sku;
  },
};

export type Quantity = number & { readonly __brand: "Quantity" };

export const Quantity = {
  of(value: number): Result<Quantity, ValidationError> {
    if (!Number.isInteger(value)) {
      return Err({ field: "Quantity", message: "must be an integer", value });
    }
    if (!(value >= 1 && value <= 9999)) {
      return Err({ field: "Quantity", message: "must be in range [1, 9999]", value });
    }
    return Ok(value as Quantity);
  },
  unsafe(value: number): Quantity {
    return value as Quantity;
  },
};

export type Discount = number & { readonly __brand: "Discount" };

export const Discount = {
  of(value: number): Result<Discount, ValidationError> {
    if (!Number.isInteger(value)) {
      return Err({ field: "Discount", message: "must be an integer", value });
    }
    if (!(value >= 0 && value <= 100)) {
      return Err({ field: "Discount", message: "must be in range [0, 100]", value });
    }
    return Ok(value as Discount);
  },
  unsafe(value: number): Discount {
    return value as Discount;
  },
};

export function parseSku(s: string): Result<Sku, ValidationError> {
  return Sku.of(s);
}

export function applyDiscount(qty: number, discount: number): Result<number, ValidationError> {
  const __r0 = Quantity.of(qty);
  if (__r0.tag === "Err") return __r0;
  const q = __r0.value;
  const __r1 = Discount.of(discount);
  if (__r1.tag === "Err") return __r1;
  const d = __r1.value;
  const amount = q * 100;
  const reduction = Math.trunc(amount * d / 100);
  return Ok(amount - reduction);
}

export function classifyQuantity(qty: number): Result<string, ValidationError> {
  const __r0 = Quantity.of(qty);
  if (__r0.tag === "Err") return __r0;
  const q = __r0.value;
  return (q < 10 ? Ok("small") : (q < 100 ? Ok("medium") : Ok("large")));
}

