// Cálculos de ROI de automatización — funciones puras, sin dependencias de UI ni persistencia.
// Fórmulas nominales simples (ADR-014): sin VPN, TIR ni tasa de descuento.
// Los edge cases (inversión cero, ahorro negativo, división por cero) están explicitados.

export interface RoiInput {
  costPerExecutionActual: number     // costo total de una ejecución en escenario actual
  costPerExecutionAutomated: number  // costo total de una ejecución en escenario automatizado
  annualFrequency: number            // ejecuciones por año
  analysisHorizonYears: number       // horizonte de análisis en años
  automationInvestment: number       // inversión total única del proyecto de automatización
}

export interface RoiResult {
  savingsPerExecution: number        // ahorro por ejecución individual (actual - automatizado)
  savingsPerExecutionPercent: number // ahorro % sobre el costo actual (0 si actual = 0)
  annualSavings: number              // ahorro anual = ahorro/ejecución × frecuencia
  paybackMonths: number              // meses para recuperar inversión (Infinity si ahorro <= 0)
  paybackYears: number               // años para recuperar inversión
  cumulativeSavingsHorizon: number   // ahorro acumulado neto al final del horizonte
  breaksEvenInHorizon: boolean       // ¿el payback ocurre dentro del horizonte?
  roiAnnualPercent: number           // ROI anualizado % = (ahorroAnual / inversión) × 100
                                     // Infinity si inversión = 0 y ahorro > 0
}

export function calculateRoi(input: RoiInput): RoiResult {
  const {
    costPerExecutionActual,
    costPerExecutionAutomated,
    annualFrequency,
    analysisHorizonYears,
    automationInvestment,
  } = input

  const savingsPerExecution = costPerExecutionActual - costPerExecutionAutomated

  // Evitar división por cero cuando el costo actual es 0
  const savingsPerExecutionPercent =
    costPerExecutionActual > 0
      ? (savingsPerExecution / costPerExecutionActual) * 100
      : 0

  const annualSavings = savingsPerExecution * annualFrequency

  // Payback: si no hay ahorro (o es negativo), nunca se recupera la inversión
  let paybackMonths: number
  if (annualSavings <= 0) {
    paybackMonths = Infinity
  } else if (automationInvestment === 0) {
    // Inversión cero con ahorro positivo: recuperación instantánea
    paybackMonths = 0
  } else {
    paybackMonths = (automationInvestment / annualSavings) * 12
  }

  const paybackYears = paybackMonths / 12  // Infinity / 12 = Infinity, 0 / 12 = 0

  const cumulativeSavingsHorizon = annualSavings * analysisHorizonYears - automationInvestment

  const breaksEvenInHorizon = isFinite(paybackYears) && paybackYears <= analysisHorizonYears

  // ROI anualizado: Infinity si inversión = 0 con ahorro > 0; 0 si inversión = 0 y ahorro = 0
  let roiAnnualPercent: number
  if (automationInvestment === 0) {
    roiAnnualPercent = annualSavings > 0 ? Infinity : 0
  } else {
    roiAnnualPercent = (annualSavings / automationInvestment) * 100
  }

  return {
    savingsPerExecution,
    savingsPerExecutionPercent,
    annualSavings,
    paybackMonths,
    paybackYears,
    cumulativeSavingsHorizon,
    breaksEvenInHorizon,
    roiAnnualPercent,
  }
}
