import { prisma } from '../lib/prisma'
import { resolveSettingsEntitlements } from '../modules/companies/settingsEntitlements'

interface DriverInfo {
  dateOfBirth?: Date | null
  licenseIssuedAt?: Date | null
}

export async function applyPricingRules(
  companyId: string,
  customerId: string,
  additionalDrivers: DriverInfo[],
  dailyRate: number,
  totalDays: number
): Promise<{ applied: any[]; total: number }> {
  const entitlements = await resolveSettingsEntitlements(companyId)
  if (!entitlements.features['settings.pricing_rules']?.available) {
    return { applied: [], total: 0 }
  }

  const rules = await prisma.pricingRule.findMany({ where: { companyId, isActive: true } })
  const customer = await prisma.customer.findFirstOrThrow({ where: { id: customerId, companyId } })
  const allDrivers: DriverInfo[] = [customer, ...additionalDrivers]
  const applied: any[] = []
  const baseAmount = dailyRate * totalDays

  for (const driver of allDrivers) {
    for (const rule of rules) {
      const driverAge = driver.dateOfBirth
        ? Math.floor((Date.now() - driver.dateOfBirth.getTime()) / (365.25 * 24 * 60 * 60 * 1000))
        : null
      const licenseYears = driver.licenseIssuedAt
        ? Math.floor((Date.now() - driver.licenseIssuedAt.getTime()) / (365.25 * 24 * 60 * 60 * 1000))
        : null

      let conditionMet = false
      if (rule.condition === 'AGE_LESS_THAN' && driverAge !== null)         conditionMet = driverAge < rule.conditionValue
      else if (rule.condition === 'AGE_GREATER_THAN' && driverAge !== null) conditionMet = driverAge > rule.conditionValue
      else if (rule.condition === 'LICENSE_YEARS_LESS_THAN' && licenseYears !== null)    conditionMet = licenseYears < rule.conditionValue
      else if (rule.condition === 'LICENSE_YEARS_GREATER_THAN' && licenseYears !== null) conditionMet = licenseYears > rule.conditionValue

      if (!conditionMet) continue

      let amount = 0
      if (rule.adjustmentType === 'PERCENTAGE')   amount = Math.round(baseAmount * rule.adjustmentValue / 100)
      else if (rule.adjustmentType === 'FLAT_PER_DAY') amount = rule.adjustmentValue * totalDays
      else                                        amount = rule.adjustmentValue

      if (rule.type === 'DISCOUNT') amount = -amount
      applied.push({ ruleId: rule.id, name: rule.name, type: rule.type, amount })
    }
  }

  // Deduplicate: each rule applied once even if multiple drivers qualify
  const deduped = applied.reduce((acc: any[], item) => {
    if (!acc.find((a) => a.ruleId === item.ruleId)) acc.push(item)
    return acc
  }, [])

  const total = deduped.reduce((s: number, r: any) => s + r.amount, 0)
  return { applied: deduped, total }
}
