import { useMemo, type CSSProperties, type ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import { Line } from 'react-chartjs-2';
import {
IconDiamond,
IconDollarSign,
IconSatellite,
IconTimer,
IconTrendingUp,
} from '@/components/ui/icons';
import {
formatCompactNumber,
formatPerMinuteValue,
formatUsd,
} from '@/utils/usage';
import { sparklineOptions } from '@/utils/usage/chartConfig';
import type { UsageOverviewPayload } from './hooks/useUsageData';
import type { SparklineBundle } from './hooks/useSparklines';
import styles from '@/pages/UsagePage.module.scss';
interface StatCardData {
key: string;
label: string;
icon: ReactNode;
accent: string;
accentSoft: string;
accentBorder: string;
value: string;
meta?: ReactNode;
trend: SparklineBundle | null;
}
export interface StatCardsProps {
usage: UsageOverviewPayload | null;
loading: boolean;
sparklines: {
requests: SparklineBundle | null;
tokens: SparklineBundle | null;
rpm: SparklineBundle | null;
tpm: SparklineBundle | null;
cost: SparklineBundle | null;
};
}
interface StatCardMetrics {
tokenBreakdown: { cachedTokens: number; reasoningTokens: number };
rateStats: { rpm: number; tpm: number; windowMinutes: number; requestCount: number; tokenCount: number };
totalCost: number;
costAvailable: boolean;
}
export function buildStatCardMetrics({ usage }: { usage: UsageOverviewPayload | null }): StatCardMetrics {
if (!usage?.summary) {
return {
tokenBreakdown: { cachedTokens: 0, reasoningTokens: 0 },
rateStats: { rpm: 0, tpm: 0, windowMinutes: 1, requestCount: 0, tokenCount: 0 },
totalCost: 0,
costAvailable: false,
};
}
return {
tokenBreakdown: {
cachedTokens: usage.summary.cached_tokens ?? 0,
reasoningTokens: usage.summary.reasoning_tokens ?? 0,
},
rateStats: {
rpm: usage.summary.rpm ?? 0,
tpm: usage.summary.tpm ?? 0,
windowMinutes: usage.summary.window_minutes ?? 1,
requestCount: usage.summary.request_count ?? 0,
tokenCount: usage.summary.token_count ?? 0,
},
totalCost: usage.summary.total_cost ?? 0,
costAvailable: usage.summary.cost_available === true,
};
}
export function StatCards({ usage, loading, sparklines }: StatCardsProps) {
const { t } = useTranslation();
const usageSnapshot = usage?.usage ?? null;
const { tokenBreakdown, rateStats, totalCost, costAvailable } = useMemo(
() => buildStatCardMetrics({ usage }),
[usage]
);
const statsCards: StatCardData[] = [
{
key: 'requests',
label: t('usage_stats.total_requests'),
icon: