import { MeteringValidationError } from './errors.js'
import type { RatingRule } from './types.js'

/**
 * Converts units with fixed-point bigint arithmetic.
 * Bigint division truncates toward zero; usage events retain ruleVersion and are never recomputed.
 * Optional ledger balance projection posts through a durable outbox and idempotent projector, not a synchronous commit dual-write.
 */
export function rate(units: bigint, rule: RatingRule): bigint {
  if (typeof units !== 'bigint') {
    throw new MeteringValidationError('units', 'must be a bigint')
  }
  if (typeof rule !== 'object' || rule === null) {
    throw new MeteringValidationError('rule', 'must be an object')
  }
  if (typeof rule.numerator !== 'bigint') {
    throw new MeteringValidationError('rule.numerator', 'must be a bigint')
  }
  if (typeof rule.denominator !== 'bigint' || rule.denominator <= 0n) {
    throw new MeteringValidationError('rule.denominator', 'must be a positive bigint')
  }

  return (units * rule.numerator) / rule.denominator
}
