import { useGameStore } from '@/store'; import { formatMoney, formatPercent, FUNDING_ROUNDS } from '@ai-tycoon/shared'; import type { FundingRoundType } from '@ai-tycoon/shared'; import { TrendingUp, DollarSign, PiggyBank, BarChart3, Rocket } from 'lucide-react'; import { AreaChart, Area, XAxis, YAxis, ResponsiveContainer, LineChart, Line } from 'recharts'; import { canRaiseFunding } from '@ai-tycoon/game-engine'; import type { GameState } from '@ai-tycoon/shared'; export function FinancePage() { const money = useGameStore((s) => s.economy.money); const revenuePerTick = useGameStore((s) => s.economy.revenuePerTick); const expensesPerTick = useGameStore((s) => s.economy.expensesPerTick); const funding = useGameStore((s) => s.economy.funding); const history = useGameStore((s) => s.economy.financialHistory); const infrastructure = useGameStore((s) => s.infrastructure); const talent = useGameStore((s) => s.talent); const raiseFunding = useGameStore((s) => s.raiseFunding); const state = useGameStore.getState(); const gameStateForFunding: GameState = { meta: state.meta, economy: state.economy, infrastructure: state.infrastructure, compute: state.compute, research: state.research, models: state.models, market: state.market, competitors: state.competitors, talent: state.talent, data: state.data, reputation: state.reputation, events: state.events, achievements: state.achievements, }; const fundingStatus = canRaiseFunding(gameStateForFunding); const netIncome = revenuePerTick - expensesPerTick; const burnRate = expensesPerTick > revenuePerTick ? expensesPerTick - revenuePerTick : 0; const runway = burnRate > 0 ? money / burnRate : Infinity; const infraCosts = infrastructure.dataCenters.reduce( (s, dc) => s + dc.energyCostPerTick + dc.maintenanceCostPerTick, 0, ); const talentCosts = talent.totalSalaryPerTick; return (

Finance

= 0 ? 'text-green-400' : 'text-red-400'} />

Cash Over Time

{history.length > 1 ? ( ) : (
Data will appear as time passes
)}

Revenue vs Expenses

{history.length > 1 ? ( ) : (
Data will appear as time passes
)}

Income Statement (per second)

Revenue {formatMoney(revenuePerTick)}
Infrastructure -{formatMoney(infraCosts)}
Talent -{formatMoney(talentCosts)}
Total Expenses -{formatMoney(expensesPerTick)}
Net Income = 0 ? 'text-success' : 'text-danger'}`}> {formatMoney(netIncome)}

Funding

Founder Equity: {formatPercent(funding.founderEquity)}
Total Raised: {formatMoney(funding.totalRaised)}
{funding.isPublic && ( Public )}
{fundingStatus.nextRound && (

{fundingStatus.nextRound === 'ipo' ? 'IPO' : fundingStatus.nextRound.replace('series', 'Series ')}

{fundingStatus.canRaise ? ( ) : ( {String(fundingStatus.reason ?? '')} )}
)} {funding.completedRounds.length === 0 ? (

No funding rounds completed yet.

) : (
{funding.completedRounds.map((round, i) => (
{round.type === 'ipo' ? 'IPO' : round.type.replace('series', 'Series ')}
{formatMoney(round.amount)} {formatPercent(round.dilution)} dilution
))}
)}
); } function FinanceCard({ icon: Icon, label, value, color }: { icon: typeof DollarSign; label: string; value: string; color: string; }) { return (
{label}
{value}
); }