import type React from 'react';
import { useGameStore, type ActivePage } from '@/store';
import { formatMoney, formatNumber, formatPercent, formatDuration } from '@ai-tycoon/shared';
import type { Era } from '@ai-tycoon/shared';
import { TECH_TREE } from '@ai-tycoon/game-engine';
import {
DollarSign, TrendingUp, TrendingDown, Minus, Cpu, Brain, Users,
Shield, ChevronRight, Zap, Wifi, Sparkles, FlaskConical, Building2,
HardDrive, Clock,
} from 'lucide-react';
import {
XAxis, YAxis, Tooltip, ResponsiveContainer, Area, AreaChart, Line, LineChart,
} from 'recharts';
import { TutorialHint } from '@/components/game/TutorialHint';
const ERA_ORDER: Era[] = ['startup', 'scaleup', 'bigtech', 'agi'];
function isEraAtLeast(current: Era, threshold: Era): boolean {
return ERA_ORDER.indexOf(current) >= ERA_ORDER.indexOf(threshold);
}
export function DashboardPage() {
const money = useGameStore((s) => s.economy.money);
const revenuePerTick = useGameStore((s) => s.economy.revenuePerTick);
const expensesPerTick = useGameStore((s) => s.economy.expensesPerTick);
const financialHistory = useGameStore((s) => s.economy.financialHistory);
const totalFlops = useGameStore((s) => s.infrastructure.totalFlops);
const totalDCs = useGameStore((s) => s.infrastructure.totalDataCenterCount);
const clusters = useGameStore((s) => s.infrastructure.clusters);
const baseModels = useGameStore((s) => s.models.baseModels);
const activePipelines = useGameStore((s) => s.models.activeTrainingPipelines);
const subscribers = useGameStore((s) => s.market.consumerTiers.totalUsers);
const satisfaction = useGameStore((s) => s.market.consumerTiers.satisfaction);
const reputation = useGameStore((s) => s.reputation.score);
const reputationHistory = useGameStore((s) => s.reputation.reputationHistory);
const inferenceUtil = useGameStore((s) => s.compute.inferenceUtilization);
const effectiveInferenceFlops = useGameStore((s) => s.compute.effectiveInferenceFlops);
const trainingAllocation = useGameStore((s) => s.compute.trainingAllocation);
const computeHistory = useGameStore((s) => s.compute.computeHistory);
const totalUptime = useGameStore((s) => s.infrastructure.totalUptime);
const modelFreshness = useGameStore((s) => s.market.obsolescence.playerModelFreshness);
const era = useGameStore((s) => s.meta.currentEra);
const activeResearch = useGameStore((s) => s.research.activeResearch);
const tam = useGameStore((s) => s.market.tam);
const competitors = useGameStore((s) => s.competitors.rivals);
const netIncome = revenuePerTick - expensesPerTick;
const scaleup = isEraAtLeast(era, 'scaleup');
const hasDeployedModel = baseModels.some(m => m.isDeployed);
const bestDeployedCapability = baseModels
.filter(m => m.isDeployed)
.reduce((best, m) => Math.max(best, m.rawCapability), 0);
const revenueTrend = (() => {
if (financialHistory.length < 6) return 'neutral' as const;
const recent = financialHistory[financialHistory.length - 1].revenue;
const earlier = financialHistory[financialHistory.length - 6].revenue;
if (recent > earlier * 1.01) return 'up' as const;
if (recent < earlier * 0.99) return 'down' as const;
return 'neutral' as const;
})();
const repTrend = (() => {
if (reputationHistory.length < 2) return 'neutral' as const;
const last = reputationHistory[reputationHistory.length - 1].score;
const prev = reputationHistory[reputationHistory.length - 2].score;
if (last > prev) return 'up' as const;
if (last < prev) return 'down' as const;
return 'neutral' as const;
})();
const constructingDCs = clusters.reduce((count, cluster) => {
for (const campus of cluster.campuses) {
for (const dc of campus.dataCenters) {
if (dc.status === 'constructing') count++;
}
}
return count;
}, 0);
const deployingRacks = clusters.reduce((count, cluster) => {
for (const campus of cluster.campuses) {
for (const dc of campus.dataCenters) {
count += dc.deploymentCohorts.length;
}
}
return count;
}, 0);
const navigate = useGameStore.getState().setActivePage;
return (
Dashboard
{totalDCs === 0 && (
Welcome to AI Tycoon! Start by building a cluster in the Infrastructure tab, then add a campus and data center to deploy racks and train your first AI model.
)}
{totalDCs > 0 && baseModels.length === 0 && activePipelines.length === 0 && (
You have compute available! Head to the Models tab to allocate compute for training and start your first model.
)}
{baseModels.length > 0 && !baseModels.some(m => m.isDeployed) && (
Your model is trained! Deploy it from the Models tab to start serving customers and earning revenue.
)}
{/* Section 1: Stat Cards */}