import React, { useMemo } from 'react'; import { motion } from 'framer-motion'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell, LineChart, Line, Area, ComposedChart } from 'recharts'; import { EconomicModelData } from '../types'; import { DollarSign, TrendingDown, Calendar, TrendingUp, AlertTriangle, CheckCircle } from 'lucide-react'; import CountUp from 'react-countup'; import MethodologyFooter from './MethodologyFooter'; interface EconomicModelProProps { data: EconomicModelData; } const EconomicModelPro: React.FC = ({ data }) => { const { initialInvestment, annualSavings, paybackMonths, roi3yr, savingsBreakdown } = data; // Calculate detailed cost breakdown const costBreakdown = useMemo(() => { try { const safeInitialInvestment = initialInvestment || 0; return [ { category: 'Software & Licencias', amount: safeInitialInvestment * 0.43, percentage: 43 }, { category: 'Implementación & Consultoría', amount: safeInitialInvestment * 0.29, percentage: 29 }, { category: 'Training & Change Mgmt', amount: safeInitialInvestment * 0.18, percentage: 18 }, { category: 'Contingencia (10%)', amount: safeInitialInvestment * 0.10, percentage: 10 }, ]; } catch (error) { console.error('❌ Error in costBreakdown useMemo:', error); return []; } }, [initialInvestment]); // Waterfall data (quarterly cash flow) const waterfallData = useMemo(() => { try { const safeInitialInvestment = initialInvestment || 0; const safeAnnualSavings = annualSavings || 0; const quarters = 8; // 2 years const quarterlyData = []; let cumulative = -safeInitialInvestment; // Q0: Initial investment quarterlyData.push({ quarter: 'Inv', value: -safeInitialInvestment, cumulative: cumulative, isNegative: true, label: `-€${(safeInitialInvestment / 1000).toFixed(0)}K`, }); // Q1-Q8: Quarterly savings const quarterlySavings = safeAnnualSavings / 4; for (let i = 1; i <= quarters; i++) { cumulative += quarterlySavings; const isBreakeven = cumulative >= 0 && (cumulative - quarterlySavings) < 0; quarterlyData.push({ quarter: `Q${i}`, value: quarterlySavings, cumulative: cumulative, isNegative: cumulative < 0, isBreakeven: isBreakeven, label: `€${(quarterlySavings / 1000).toFixed(0)}K`, }); } return quarterlyData; } catch (error) { console.error('❌ Error in waterfallData useMemo:', error); return []; } }, [initialInvestment, annualSavings]); // Sensitivity analysis const sensitivityData = useMemo(() => { try { const safeAnnualSavings = annualSavings || 0; const safeInitialInvestment = initialInvestment || 1; const safeRoi3yr = roi3yr || 0; const safePaybackMonths = paybackMonths || 0; return [ { scenario: 'Pesimista (-20%)', annualSavings: safeAnnualSavings * 0.8, roi3yr: ((safeAnnualSavings * 0.8 * 3) / safeInitialInvestment).toFixed(1), payback: Math.ceil((safeInitialInvestment / (safeAnnualSavings * 0.8)) * 12), color: 'text-red-600', bgColor: 'bg-red-50', }, { scenario: 'Base Case', annualSavings: safeAnnualSavings, roi3yr: typeof safeRoi3yr === 'number' ? safeRoi3yr.toFixed(1) : '0', payback: safePaybackMonths, color: 'text-blue-600', bgColor: 'bg-blue-50', }, { scenario: 'Optimista (+20%)', annualSavings: safeAnnualSavings * 1.2, roi3yr: ((safeAnnualSavings * 1.2 * 3) / safeInitialInvestment).toFixed(1), payback: Math.ceil((safeInitialInvestment / (safeAnnualSavings * 1.2)) * 12), color: 'text-green-600', bgColor: 'bg-green-50', }, ]; } catch (error) { console.error('❌ Error in sensitivityData useMemo:', error); return []; } }, [annualSavings, initialInvestment, roi3yr, paybackMonths]); // Comparison with alternatives const alternatives = useMemo(() => { try { const safeRoi3yr = roi3yr || 0; const safeInitialInvestment = initialInvestment || 50000; // Default investment const safeAnnualSavings = annualSavings || 150000; // Default savings return [ { option: 'Do Nothing', investment: 0, savings3yr: 0, roi: 'N/A', risk: 'Alto', riskColor: 'text-red-600', recommended: false, }, { option: 'Solución Propuesta', investment: safeInitialInvestment || 0, savings3yr: (safeAnnualSavings || 0) * 3, roi: `${safeRoi3yr.toFixed(1)}x`, risk: 'Medio', riskColor: 'text-amber-600', recommended: true, }, { option: 'Alternativa Manual', investment: safeInitialInvestment * 0.5, savings3yr: safeAnnualSavings * 1.5, roi: '2.0x', risk: 'Bajo', riskColor: 'text-green-600', recommended: false, }, { option: 'Alternativa Premium', investment: safeInitialInvestment * 1.5, savings3yr: safeAnnualSavings * 2.3, roi: '3.3x', risk: 'Alto', riskColor: 'text-red-600', recommended: false, }, ]; } catch (error) { console.error('❌ Error in alternatives useMemo:', error); return []; } }, [initialInvestment, annualSavings, roi3yr]); // Financial metrics const financialMetrics = useMemo(() => { const npv = (annualSavings * 3 * 0.9) - initialInvestment; // Simplified NPV with 10% discount const irr = 185; // Simplified IRR estimation const tco3yr = initialInvestment + (annualSavings * 0.2 * 3); // TCO = Investment + 20% recurring costs const valueCreated = (annualSavings * 3) - tco3yr; return { npv, irr, tco3yr, valueCreated }; }, [initialInvestment, annualSavings]); try { return (
{/* Header with Dynamic Title */}

Business Case: €{((annualSavings || 0) / 1000).toFixed(0)}K en ahorros anuales con payback de {paybackMonths || 0} meses y ROI de {(typeof roi3yr === 'number' ? roi3yr : 0).toFixed(1)}x

Inversión de €{((initialInvestment || 0) / 1000).toFixed(0)}K genera retorno de €{(((annualSavings || 0) * 3) / 1000).toFixed(0)}K en 3 años

Análisis financiero completo | NPV: €{(financialMetrics.npv / 1000).toFixed(0)}K | IRR: {financialMetrics.irr}%

{/* Key Metrics */}
ROI (3 años)
Ahorro Anual
Payback
meses
NPV
{/* Cost and Savings Breakdown */}
{/* Cost Breakdown */}

Inversión Inicial (€{(initialInvestment / 1000).toFixed(0)}K)

{costBreakdown.map((item, index) => (
{item.category} €{(item.amount / 1000).toFixed(0)}K ({item.percentage}%)
))}
{/* Savings Breakdown */}

Ahorros Anuales (€{(annualSavings / 1000).toFixed(0)}K)

{savingsBreakdown && savingsBreakdown.length > 0 ? savingsBreakdown.map((item, index) => (
{item.category} €{(item.amount / 1000).toFixed(0)}K ({item.percentage}%)
)) : (

No hay datos de ahorros disponibles

)}
{/* Waterfall Chart */}

Flujo de Caja Acumulado (Waterfall)

`€${(value / 1000).toFixed(0)}K`} /> {waterfallData.map((entry, index) => ( ))}
Breakeven alcanzado en Q{Math.ceil(paybackMonths / 3)} (mes {paybackMonths})
{/* Sensitivity Analysis */}

Análisis de Sensibilidad

{sensitivityData.map((scenario, index) => ( ))}
Escenario Ahorro Anual ROI (3 años) Payback
{scenario.scenario} €{scenario.annualSavings.toLocaleString('es-ES')} {scenario.roi3yr}x {scenario.payback} meses
Variables clave: % Reducción AHT (±5pp), Adopción de usuarios (±15pp), Coste por FTE (±€10K)
{/* Comparison with Alternatives */}

Evaluación de Alternativas

{alternatives && alternatives.length > 0 ? alternatives.map((alt, index) => ( )) : ( )}
Opción Inversión Ahorro (3 años) ROI Riesgo
{alt.option} €{(alt.investment || 0).toLocaleString('es-ES')} €{(alt.savings3yr || 0).toLocaleString('es-ES')} {alt.roi} {alt.risk} {alt.recommended && ( Recomendado )}
Sin datos de alternativas disponibles
Recomendación: Solución Propuesta (mejor balance ROI/Riesgo)
{/* Summary Box */}

Resumen Ejecutivo

Con una inversión inicial de €{initialInvestment.toLocaleString('es-ES')}, se proyecta un ahorro anual de €{annualSavings.toLocaleString('es-ES')}, recuperando la inversión en {paybackMonths} meses y generando un ROI de {roi3yr.toFixed(1)}x en 3 años. El NPV de €{financialMetrics.npv.toLocaleString('es-ES')} y un IRR de {financialMetrics.irr}% demuestran la solidez financiera del proyecto.

{/* Methodology Footer */}
); } catch (error) { console.error('❌ CRITICAL ERROR in EconomicModelPro render:', error); return (

❌ Error en Modelo Económico

No se pudo renderizar el componente. Error: {String(error)}

); } }; export default EconomicModelPro;