/**
 * Volume Value Object
 * Represents shipping volume in CBM (Cubic Meters) and weight in KG
 *
 * Business Rule: Price is calculated using freight class rule:
 * - Take the higher of: (volumeCBM * pricePerCBM) or (weightKG * pricePerKG)
 */
export class Volume {
  constructor(
    public readonly cbm: number,
    public readonly weightKG: number
  ) {
    this.validate();
  }

  private validate(): void {
    if (this.cbm < 0) {
      throw new Error('Volume in CBM cannot be negative');
    }
    if (this.weightKG < 0) {
      throw new Error('Weight in KG cannot be negative');
    }
    if (this.cbm === 0 && this.weightKG === 0) {
      throw new Error('Either volume or weight must be greater than zero');
    }
  }

  /**
   * Check if this volume is within the specified range
   */
  isWithinRange(minCBM: number, maxCBM: number, minKG: number, maxKG: number): boolean {
    const cbmInRange = this.cbm >= minCBM && this.cbm <= maxCBM;
    const weightInRange = this.weightKG >= minKG && this.weightKG <= maxKG;
    return cbmInRange && weightInRange;
  }

  /**
   * Calculate freight price using the freight class rule
   * Returns the higher value between volume-based and weight-based pricing
   */
  calculateFreightPrice(pricePerCBM: number, pricePerKG: number): number {
    const volumePrice = this.cbm * pricePerCBM;
    const weightPrice = this.weightKG * pricePerKG;
    return Math.max(volumePrice, weightPrice);
  }

  equals(other: Volume): boolean {
    return this.cbm === other.cbm && this.weightKG === other.weightKG;
  }

  toString(): string {
    return `${this.cbm} CBM / ${this.weightKG} KG`;
  }
}
