import { useState, useEffect, useRef } from 'react' import { Loader2, Info } from 'lucide-react' import type { StrategyConfig } from '../../types' import { t, type Language } from '../../i18n/translations' const API_BASE = import.meta.env.VITE_API_BASE || '' interface ModelLimit { name: string context_limit: number usage_pct: number level: string } interface TokenEstimateResult { total: number model_limits: ModelLimit[] suggestions: string[] } interface TokenEstimateBarProps { config: StrategyConfig | null language: Language onTokenCountChange?: (total: number) => void } export function TokenEstimateBar({ config, language, onTokenCountChange }: TokenEstimateBarProps) { const [estimate, setEstimate] = useState(null) const [isLoading, setIsLoading] = useState(false) const debounceRef = useRef | null>(null) const tr = (key: string) => t(`strategyStudio.${key}`, language) useEffect(() => { if (!config) { setEstimate(null) return } if (debounceRef.current) { clearTimeout(debounceRef.current) } debounceRef.current = setTimeout(async () => { setIsLoading(true) try { const response = await fetch(`${API_BASE}/api/strategies/estimate-tokens`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ config }), }) if (response.ok) { const data = await response.json() setEstimate(data) onTokenCountChange?.(data.total) } } catch { // silently ignore — non-critical UI element } finally { setIsLoading(false) } }, 800) return () => { if (debounceRef.current) { clearTimeout(debounceRef.current) } } }, [config]) if (!config) return null if (isLoading && !estimate) { return (
{tr('tokenEstimating')}
) } if (!estimate) return null // Display based on 200K reference const pct = Math.round(estimate.total * 100 / 200000) const barWidth = Math.min(pct, 100) let barColor = '#0ECB81' // green let textColor = '#848E9C' if (pct >= 100) { barColor = '#F6465D' // red textColor = '#F6465D' } else if (pct >= 80) { barColor = '#F0B90B' // yellow textColor = '#F0B90B' } return (
{isLoading ? : `${pct}%`}
{tr('tokenTooltip')} (~{estimate.total.toLocaleString()} / 200K)
) }