import type { GameState, FundingState, FundingRoundType } from '@token-empire/shared'; import { FUNDING_ROUNDS } from '@token-empire/shared'; const ROUND_ORDER: FundingRoundType[] = ['seed', 'seriesA', 'seriesB', 'seriesC', 'seriesD', 'ipo']; export function getNextFundingRound(funding: FundingState): FundingRoundType | null { if (funding.isPublic) return null; const completedTypes = new Set(funding.completedRounds.map(r => r.type)); for (const type of ROUND_ORDER) { if (!completedTypes.has(type)) return type; } return null; } export function canRaiseFunding(state: GameState): { canRaise: boolean; nextRound: FundingRoundType | null; reason?: string } { const nextRound = getNextFundingRound(state.economy.funding); if (!nextRound) return { canRaise: false, nextRound: null, reason: 'No more funding rounds available' }; const config = FUNDING_ROUNDS[nextRound]; const reqs = config.requirements; if (reqs.minRevenue && state.economy.totalRevenue < reqs.minRevenue) { return { canRaise: false, nextRound, reason: `Need $${reqs.minRevenue.toLocaleString()} total revenue` }; } if (reqs.minUsers && state.market.consumerTiers.totalUsers < reqs.minUsers) { return { canRaise: false, nextRound, reason: `Need ${reqs.minUsers.toLocaleString()} subscribers` }; } if (reqs.minReputation && state.reputation.score < reqs.minReputation) { return { canRaise: false, nextRound, reason: `Need ${reqs.minReputation} reputation` }; } return { canRaise: true, nextRound }; } export function computeValuation(state: GameState): number { const revenueMultiple = state.economy.revenuePerTick * 86400 * 365; const subscriberValue = state.market.consumerTiers.totalUsers * 500; const capabilityValue = Math.pow(state.models.bestDeployedModelScore, 2) * 1000; return Math.max(100_000, revenueMultiple * 10 + subscriberValue + capabilityValue); }