import Customer from '#models/customer'
import IntlCourierRateGroup from '#models/intl_courier_rate_group'
import { IntlCouriers, IntlCouriersRateType } from '../../types/enum.js'

export const intlCourierRateCalculatorHelper = async ({
  rate,
  courier,
  customer_id,
  weight,
}: {
  rate: number
  courier: IntlCouriers
  customer_id: number
  weight: number
}): Promise<{
  courierRate: number
  margin: number
  finalRate: number
}> => {
  const customerDetails = await Customer.query()
    .where('id', customer_id)
    .preload('intl_courier_rate_group_details', (groupQuery) => {
      groupQuery.where('is_active', true)
      groupQuery.preload('intl_courier_rate_details', (rateQuery) => {
        rateQuery
          .where('weight_from', '<=', weight)
          .andWhere('weight_to', '>', weight)
          .where('courier', courier as IntlCouriers)
      })
    })
    .first()

  let intlCourierRate =
    customerDetails?.intl_courier_rate_group_details?.intl_courier_rate_details?.[0]

  if (!intlCourierRate) {
    const data = await IntlCourierRateGroup.query()
      .where('is_default', true)
      .andWhere('is_active', true)
      .whereHas('intl_courier_rate_details', (rateQuery) => {
        rateQuery
          .where('weight_from', '<=', weight)
          .andWhere('weight_to', '>', weight)
          .where('courier', courier as IntlCouriers)
      })
      .preload('intl_courier_rate_details', (rateQuery) => {
        rateQuery
          .where('weight_from', '<=', weight)
          .andWhere('weight_to', '>', weight)
          .where('courier', courier as IntlCouriers)
          .first()
      })
      .first()

    intlCourierRate = data?.intl_courier_rate_details?.[0]
  }

  if (!intlCourierRate) {
    throw new Error('No international courier rate found for the given criteria.')
  }

  let calculatedRate: { courierRate: number; margin: number; finalRate: number } = {
    courierRate: rate,
    margin: 0,
    finalRate: rate,
  }

  switch (intlCourierRate.rate_type) {
    case IntlCouriersRateType.Addition:
      const additionMargin = Number(intlCourierRate.value)
      calculatedRate.margin = additionMargin
      calculatedRate.finalRate = rate + additionMargin

      break

    case IntlCouriersRateType.Percentage:
      const percentageMargin = (rate * Number(intlCourierRate.value)) / 100
      calculatedRate.margin = percentageMargin
      calculatedRate.finalRate = rate + percentageMargin

      break

    case IntlCouriersRateType.Multiplication:
      const multiplicationValue = Number(intlCourierRate.value)
      calculatedRate.margin = 0
      calculatedRate.finalRate = weight * multiplicationValue

      break
  }

  return calculatedRate
}
