import { BadRequestException } from '@nestjs/common';

/**
 * Engine tính toán chi phí dựa trên công thức trong ARCHITECTURE.md
 * T = N_adult * X + N_child * (X * (1 - P_child_discount))
 */
export class ExpenseEngine {
  /**
   * Tính toán phân chia chi phí giữa người lớn và trẻ em
   * @param totalCost Tổng chi phí (T)
   * @param adultCount Số lượng người lớn (N_adult)
   * @param childCount Số lượng trẻ em (N_child)
   * @param childDiscountPercent Phần trăm giảm giá trẻ em (P_child_discount, ví dụ: 30)
   */
  calculateSplit(
    totalCost: number,
    adultCount: number,
    childCount: number,
    childDiscountPercent: number
  ) {
    // 1. Validation: Kiểm tra dữ liệu đầu vào âm
    if (totalCost < 0 || adultCount < 0 || childCount < 0 || childDiscountPercent < 0) {
      throw new BadRequestException('Dữ liệu đầu vào không được là số âm.');
    }

    if (childDiscountPercent > 100) {
      throw new BadRequestException('Phần trăm giảm giá không thể vượt quá 100%.');
    }

    // 2. Handle division by zero: Không có người tham gia
    if (adultCount + childCount === 0) {
      throw new BadRequestException('Số lượng người tham gia phải lớn hơn 0.');
    }

    const discountRate = childDiscountPercent / 100;
    const childRateFactor = 1 - discountRate;
    
    /**
     * Giải phương trình:
     * T = X * N_adult + X * (1 - P) * N_child
     * T = X * (N_adult + N_child * (1 - P))
     * => X = T / (N_adult + N_child * (1 - P))
     */
    const weightedParticipantCount = adultCount + (childCount * childRateFactor);
    
    const adultPriceRaw = totalCost / weightedParticipantCount;
    const childPriceRaw = adultPriceRaw * childRateFactor;

    // Làm tròn để thực tế thanh toán (ví dụ: làm tròn đến hàng đơn vị)
    const perAdult = Math.round(adultPriceRaw);
    const perChild = Math.round(childPriceRaw);

    const adultsTotal = perAdult * adultCount;
    const childrenTotal = perChild * childCount;
    const actualSum = adultsTotal + childrenTotal;

    return {
      targetTotal: totalCost,
      actualTotal: actualSum,
      perAdult,
      perChild,
      roundingDifference: totalCost - actualSum, // Chênh lệch do làm tròn (nếu có)
      adultsTotal,
      childrenTotal,
    };
  }
}