export const CREDIT_UNIT_PRICE_CENTS = 500n
export const USD_CURRENCY = 'USD' as const
export const CONVERSION_CREDIT_COST = 1n

export type CreditQuantity = bigint
export type UsdMinorUnits = bigint

export function parseCreditQuantity(value: number | bigint): CreditQuantity {
  if (typeof value === 'bigint') {
    if (value <= 0n) throw new RangeError('Credit quantity must be a positive integer')
    return value
  }

  if (!Number.isSafeInteger(value) || value <= 0) {
    throw new RangeError('Credit quantity must be a positive safe integer')
  }
  return BigInt(value)
}

export function isValidCreditQuantity(value: unknown): value is number | bigint {
  if (typeof value === 'bigint') return value > 0n
  return typeof value === 'number' && Number.isSafeInteger(value) && value > 0
}

export function creditPurchaseTotalCents(quantity: number | bigint): UsdMinorUnits {
  return parseCreditQuantity(quantity) * CREDIT_UNIT_PRICE_CENTS
}

export type CreditProjection = Readonly<{
  spendable: bigint
  deficit: bigint
}>

export function projectCreditBalance(net: bigint): CreditProjection {
  return net >= 0n
    ? { spendable: net, deficit: 0n }
    : { spendable: 0n, deficit: -net }
}

export function canAcceptConversion(net: bigint): boolean {
  const balance = projectCreditBalance(net)
  return balance.deficit === 0n && balance.spendable >= CONVERSION_CREDIT_COST
}
