interface PriceConfig {
  basePrice: number;
  kmFlatRate: number;
  kmFlatRateUpTo: number;
  pricePerKm: number;
  kmMultiplier: number;
}

interface PriceBreakdown {
  basePrice: number;
  kmFlatRate: number;
  kmAdditionalNet: number;
  kmAdditionalGross: number;
  kmTotalGross: number;
  totalPrice: number;
  distance?: number;
}

export class PriceCalculator {
  private static readonly VAT_RATE = 1.19;

  static calculateKmCharge(
    distance: number,
    config: PriceConfig
  ): {
    kmTotalGross: number;
    kmFlatRate: number;
    kmAdditionalNet: number;
    kmAdditionalGross: number;
  } {
    const { kmFlatRate, kmFlatRateUpTo, pricePerKm, kmMultiplier } = config;

    if (distance <= kmFlatRateUpTo) {
      return {
        kmTotalGross: kmFlatRate,
        kmFlatRate: kmFlatRate,
        kmAdditionalNet: 0,
        kmAdditionalGross: 0,
      };
    }

    const extraKm = distance - kmFlatRateUpTo;
    const kmAdditionalNet = extraKm * kmMultiplier * pricePerKm;
    const kmAdditionalGross = Math.round(kmAdditionalNet * this.VAT_RATE * 100) / 100;
    const kmTotalGross = Math.round((kmFlatRate + kmAdditionalGross) * 100) / 100;

    return {
      kmTotalGross,
      kmFlatRate,
      kmAdditionalNet: Math.round(kmAdditionalNet * 100) / 100,
      kmAdditionalGross,
    };
  }

  static calculateTotalPrice(
    basePrice: number,
    distance: number | null | undefined,
    config: PriceConfig
  ): PriceBreakdown {
    if (!distance || distance <= 0) {
      return {
        basePrice,
        kmFlatRate: 0,
        kmAdditionalNet: 0,
        kmAdditionalGross: 0,
        kmTotalGross: 0,
        totalPrice: basePrice,
      };
    }

    const kmCharge = this.calculateKmCharge(distance, config);
    const totalPrice = Math.round((basePrice + kmCharge.kmTotalGross) * 100) / 100;

    return {
      basePrice,
      kmFlatRate: kmCharge.kmFlatRate,
      kmAdditionalNet: kmCharge.kmAdditionalNet,
      kmAdditionalGross: kmCharge.kmAdditionalGross,
      kmTotalGross: kmCharge.kmTotalGross,
      totalPrice,
      distance,
    };
  }

  static formatPriceBreakdown(breakdown: PriceBreakdown): string {
    const lines = [
      `Grundpreis Fotobox: ${breakdown.basePrice.toFixed(2)}€`,
    ];

    if (breakdown.distance && breakdown.distance > 0) {
      lines.push(`\nKilometerpauschale (${breakdown.distance.toFixed(1)}km):`);
      
      if (breakdown.kmFlatRate > 0) {
        lines.push(`  - Pauschale: ${breakdown.kmFlatRate.toFixed(2)}€`);
      }
      
      if (breakdown.kmAdditionalGross > 0) {
        lines.push(`  - Zusätzlich: ${breakdown.kmAdditionalGross.toFixed(2)}€`);
      }
      
      lines.push(`  = Gesamt KM: ${breakdown.kmTotalGross.toFixed(2)}€`);
    }

    lines.push(`\nGesamtpreis: ${breakdown.totalPrice.toFixed(2)}€`);

    return lines.join('\n');
  }
}
