/**
 * Value Object representing a coupon quantity (positive integer).
 * Immutable with private constructor and static factory.
 */
export class CouponQuantity {
  private constructor(private readonly _value: number) {}

  /**
   * Create a CouponQuantity from a numeric value.
   * @param value - Must be a positive integer (>= 1)
   */
  static create(value: number): CouponQuantity {
    if (!Number.isInteger(value)) {
      throw new Error('Coupon quantity must be an integer');
    }
    if (value < 1) {
      throw new Error('Coupon quantity must be at least 1');
    }
    return new CouponQuantity(value);
  }

  /**
   * Create a CouponQuantity representing a supply amount (allows 0).
   * Used for remaining supply which can reach 0.
   * @param value - Must be a non-negative integer (>= 0)
   */
  static createSupply(value: number): CouponQuantity {
    if (!Number.isInteger(value)) {
      throw new Error('Supply quantity must be an integer');
    }
    if (value < 0) {
      throw new Error('Supply quantity cannot be negative');
    }
    return new CouponQuantity(value);
  }

  get value(): number {
    return this._value;
  }

  subtract(amount: CouponQuantity): CouponQuantity {
    const result = this._value - amount._value;
    if (result < 0) {
      throw new Error('Insufficient quantity: cannot subtract more than available');
    }
    return new CouponQuantity(result);
  }

  add(amount: CouponQuantity): CouponQuantity {
    return new CouponQuantity(this._value + amount._value);
  }

  isZero(): boolean {
    return this._value === 0;
  }

  isGreaterThanOrEqual(amount: CouponQuantity): boolean {
    return this._value >= amount._value;
  }

  equals(other: CouponQuantity): boolean {
    return this._value === other._value;
  }

  toString(): string {
    return String(this._value);
  }
}
