'use client' import { FMResult } from '@/lib/types' import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, ReferenceLine, Line, ComposedChart, Cell, } from 'recharts' interface AnnualCashflowChartProps { results: FMResult[] initialFunding: number lang: 'de' | 'en' } interface AnnualCFRow { year: string revenue: number costs: number netCashflow: number cashBalance: number cumulativeFundingNeed: number } export default function AnnualCashflowChart({ results, initialFunding, lang }: AnnualCashflowChartProps) { const de = lang === 'de' // Aggregate into yearly const yearMap = new Map() for (const r of results) { if (!yearMap.has(r.year)) yearMap.set(r.year, []) yearMap.get(r.year)!.push(r) } let cumulativeNeed = 0 const data: AnnualCFRow[] = Array.from(yearMap.entries()).map(([year, months]) => { const revenue = months.reduce((s, m) => s + m.revenue_eur, 0) const costs = months.reduce((s, m) => s + m.total_costs_eur, 0) const netCF = revenue - costs const lastMonth = months[months.length - 1] // Cumulative funding need: how much total external capital is needed if (netCF < 0) cumulativeNeed += Math.abs(netCF) return { year: year.toString(), revenue: Math.round(revenue), costs: Math.round(costs), netCashflow: Math.round(netCF), cashBalance: Math.round(lastMonth.cash_balance_eur), cumulativeFundingNeed: Math.round(cumulativeNeed), } }) const formatValue = (value: number) => { if (Math.abs(value) >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}M` if (Math.abs(value) >= 1_000) return `${(value / 1_000).toFixed(0)}k` return value.toString() } // Calculate total funding needed beyond initial funding const totalFundingGap = Math.max(0, cumulativeNeed - initialFunding) return (
{/* Summary Cards */}

{de ? 'Startkapital' : 'Initial Funding'}

{formatValue(initialFunding)} EUR

{de ? 'Kum. Finanzbedarf' : 'Cum. Funding Need'}

{formatValue(cumulativeNeed)} EUR

{de ? 'Finanzierungsluecke' : 'Funding Gap'}

0 ? 'text-red-400' : 'text-emerald-400'}`}> {totalFundingGap > 0 ? formatValue(totalFundingGap) + ' EUR' : (de ? 'Gedeckt' : 'Covered')}

{/* Chart */}
{ const label = name === 'netCashflow' ? (de ? 'Netto-Cashflow' : 'Net Cash Flow') : name === 'cashBalance' ? (de ? 'Cash-Bestand' : 'Cash Balance') : name === 'cumulativeFundingNeed' ? (de ? 'Kum. Finanzbedarf' : 'Cum. Funding Need') : name return [formatValue(value) + ' EUR', label] }} /> {/* Net Cashflow Bars */} {data.map((entry, i) => ( = 0 ? 'rgba(34, 197, 94, 0.7)' : 'rgba(239, 68, 68, 0.6)'} /> ))} {/* Cash Balance Line */} {/* Cumulative Funding Need Line */}
{/* Legend */}
{de ? 'Netto-Cashflow' : 'Net Cash Flow'} {de ? 'Cash-Bestand' : 'Cash Balance'} {de ? 'Kum. Finanzbedarf' : 'Cum. Funding Need'}
) }