import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
import { cn } from '@/lib/utils';
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import { GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components';
import { buildEChartsTheme } from './buildEChartsTheme';
import { useThemeEpoch } from './useThemeEpoch';
import {
  Play,
  Loader2,
  BarChart3,
  TrendingDown,
  TrendingUp,
  AlertTriangle,
  Plus,
  History,
} from 'lucide-react';

echarts.use([LineChart, CanvasRenderer, GridComponent, TooltipComponent, LegendComponent, TitleComponent]);

interface BenchTabProps {
  providerIds: string[];
}

interface BenchSuite {
  id: string;
  name: string;
  providerId: string;
  model: string;
  promptTokens: number[];
  genTokens: number[];
  concurrency: number[];
  repetitions: number;
  createdAt: string;
}

interface BenchRun {
  id: string;
  suiteId: string;
  jobType: string;
  status: string;
  startedAt: string | null;
  finishedAt: string | null;
  totalSamples: number;
  completedSamples: number;
  concurrentForeignRequests: number;
  regressionFlag: 'baseline' | 'regression' | 'improvement' | null;
  aggregate: Record<string, unknown> | null;
  error: string | null;
  createdAt: string;
}

interface BenchSample {
  id: number;
  promptTokens: number;
  genTokens: number;
  concurrency: number;
  repetition: number;
  ttftMs: number | null;
  totalMs: number | null;
  promptTps: number | null;
  genTps: number | null;
  cacheN: number | null;
  error: string | null;
}

function parsePositiveIntegerList(value: string): number[] {
  return value
    .split(',')
    .map((s) => Number.parseInt(s.trim(), 10))
    .filter((n) => Number.isFinite(n) && n > 0);
}

export function BenchTab({ providerIds }: BenchTabProps) {
  const [view, setView] = useState<'launcher' | 'history' | 'results'>('launcher');
  const [suites, setSuites] = useState<BenchSuite[]>([]);
  const [runs, setRuns] = useState<BenchRun[]>([]);
  const [selectedRun, setSelectedRun] = useState<BenchRun | null>(null);
  const [samples, setSamples] = useState<BenchSample[]>([]);
  const [loading, setLoading] = useState(false);
  const [running, setRunning] = useState(false);
  const [recentTraffic, setRecentTraffic] = useState(false);
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const chartRef = useRef<HTMLDivElement>(null);
  const historyChartRef = useRef<HTMLDivElement>(null);
  const themeEpoch = useThemeEpoch();

  // Suite form state
  const [suiteName, setSuiteName] = useState('');
  const [suiteProvider, setSuiteProvider] = useState('');
  const [suiteModel, setSuiteModel] = useState('');
  const [suitePromptTokens, setSuitePromptTokens] = useState('256,512,1024');
  const [suiteGenTokens, setSuiteGenTokens] = useState('64,128,256');
  const [suiteConcurrency, setSuiteConcurrency] = useState('1,2,4');
  const [suiteRepetitions, setSuiteRepetitions] = useState('3');

  useEffect(() => {
    loadSuites();
    loadRuns();
  }, []);

  // N2: Clear polling interval on unmount.
  useEffect(() => {
    return () => {
      if (pollRef.current) {
        clearInterval(pollRef.current);
      }
    };
  }, []);

  useEffect(() => {
    if (view === 'history' && historyChartRef.current && runs.length > 0) {
      renderHistoryChart();
    }
  }, [view, runs, themeEpoch]);

  useEffect(() => {
    if (view === 'results' && chartRef.current && selectedRun && samples.length > 0) {
      renderResultsChart();
    }
  }, [view, selectedRun, samples, themeEpoch]);

  const loadSuites = useCallback(async () => {
    try {
      const res = await fetch('/api/control/bench/suites');
      if (!res.ok) return;
      const data = await res.json() as { suites: BenchSuite[] };
      setSuites(data.suites);
    } catch {
      // silent
    }
  }, []);

  const loadRuns = useCallback(async (): Promise<BenchRun[] | null> => {
    try {
      const res = await fetch('/api/control/bench/runs');
      if (!res.ok) return null;
      const data = await res.json() as { runs: BenchRun[] };
      setRuns(data.runs);
      return data.runs;
    } catch {
      // silent
      return null;
    }
  }, []);

  const loadRunDetails = useCallback(async (runId: string) => {
    try {
      const res = await fetch(`/api/control/bench/runs/${runId}`);
      if (!res.ok) return;
      const data = await res.json() as { run: BenchRun; samples: BenchSample[] };
      setSelectedRun(data.run);
      setSamples(data.samples);
      setView('results');
    } catch {
      // silent
    }
  }, []);

  const suiteValidation = useMemo(() => {
    const promptTokens = parsePositiveIntegerList(suitePromptTokens);
    const genTokens = parsePositiveIntegerList(suiteGenTokens);
    const concurrency = parsePositiveIntegerList(suiteConcurrency);
    const repetitions = Number.parseInt(suiteRepetitions, 10);

    if (!suiteName.trim()) return { reason: 'Name is required', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!suiteProvider) return { reason: 'Provider is required', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!suiteModel.trim()) return { reason: 'Model is required', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!promptTokens.length) return { reason: 'Prompt tokens must include at least one positive number', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!genTokens.length) return { reason: 'Gen tokens must include at least one positive number', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!concurrency.length) return { reason: 'Concurrency must include at least one positive number', promptTokens, genTokens, concurrency, repetitions: 1 };
    if (!Number.isFinite(repetitions) || repetitions < 1) return { reason: 'Repetitions must be 1 or greater', promptTokens, genTokens, concurrency, repetitions: 1 };

    return { reason: null, promptTokens, genTokens, concurrency, repetitions };
  }, [suiteConcurrency, suiteGenTokens, suiteModel, suiteName, suitePromptTokens, suiteProvider, suiteRepetitions]);

  const activeRun = useMemo(() => {
    return runs.find((run) => run.status !== 'completed' && run.status !== 'failed') ?? null;
  }, [runs]);

  const createSuite = async () => {
    if (suiteValidation.reason) return;

    const { promptTokens, genTokens, concurrency, repetitions } = suiteValidation;

    try {
      const res = await fetch('/api/control/bench/suite', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: suiteName.trim(),
          providerId: suiteProvider,
          model: suiteModel.trim(),
          promptTokens,
          genTokens,
          concurrency,
          repetitions,
        }),
      });
      if (res.ok) {
        await loadSuites();
        setSuiteName('');
      }
    } catch {
      // silent
    }
  };

  const runBench = async (suiteId: string) => {
    setLoading(true);
    setRunning(true);
    try {
      const res = await fetch('/api/control/bench/run', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ suiteId }),
      });
      const data = await res.json().catch(() => ({}));
      if (data.recentTraffic) {
        setRecentTraffic(true);
      }
    } catch {
      // silent
    } finally {
      setLoading(false);
    }

    // Poll for completion
    pollRef.current = setInterval(async () => {
      const freshRuns = await loadRuns();
      const latestRun = freshRuns?.[0];
      if (latestRun && (latestRun.status === 'completed' || latestRun.status === 'failed')) {
        if (pollRef.current) {
          clearInterval(pollRef.current);
          pollRef.current = null;
        }
        setRunning(false);
      }
    }, 2000);

    // Timeout after 10 minutes
    setTimeout(() => {
      if (pollRef.current) {
        clearInterval(pollRef.current);
        pollRef.current = null;
      }
      setRunning(false);
      loadRuns();
    }, 600_000);
  };

  const loadBaselines = useCallback(async () => {
    try {
      const res = await fetch('/api/control/bench/baselines');
      if (!res.ok) return;
      return await res.json() as { baselines: Array<{ providerId: string; model: string; aggregate: Record<string, unknown> | null }> };
    } catch {
      return { baselines: [] };
    }
  }, []);

  const [_baselines, setBaselines] = useState<Array<{ providerId: string; model: string; aggregate: Record<string, unknown> | null }>>([]);

  useEffect(() => {
    loadBaselines().then((d) => setBaselines(d?.baselines ?? []));
  }, [loadBaselines]);

  const getRegressionFlag = (aggregate: Record<string, unknown> | null, baselineAggregate: Record<string, unknown> | null): 'baseline' | 'regression' | 'improvement' | null => {
    if (!aggregate || !baselineAggregate) return null;
    const currentGenTps = aggregate.avgGenTps as number | undefined;
    const baselineGenTps = baselineAggregate.avgGenTps as number | undefined;
    if (currentGenTps == null || baselineGenTps == null) return null;
    // N5: guard against divide-by-zero.
    if (baselineGenTps === 0) return null;

    const delta = (currentGenTps - baselineGenTps) / baselineGenTps;
    if (delta < -0.1) return 'regression';
    if (delta > 0.05) return 'improvement';
    return 'baseline';
  };

  const renderResultsChart = () => {
    if (!chartRef.current || !samples.length) return;

    const instance = echarts.getInstanceByDom(chartRef.current);
    if (instance) instance.dispose();

    const theme = buildEChartsTheme();

    // Group samples by concurrency, compute avg TTFT
    const byConcurrency = new Map<number, { ttfts: number[]; genTps: number[] }>();
    for (const s of samples) {
      if (!byConcurrency.has(s.concurrency)) {
        byConcurrency.set(s.concurrency, { ttfts: [], genTps: [] });
      }
      const group = byConcurrency.get(s.concurrency)!;
      if (s.ttftMs != null) group.ttfts.push(s.ttftMs);
      if (s.genTps != null) group.genTps.push(s.genTps);
    }

    const sorted = Array.from(byConcurrency.entries()).sort((a, b) => a[0] - b[0]);
    const concurrencies = sorted.map(([c]) => c);
    const avgTtft = sorted.map(([, g]) => g.ttfts.length ? g.ttfts.reduce((a, b) => a + b, 0) / g.ttfts.length : 0);
    const avgGenTps = sorted.map(([, g]) => g.genTps.length ? g.genTps.reduce((a, b) => a + b, 0) / g.genTps.length : 0);

    echarts.init(chartRef.current, theme as echarts.EChartsCoreOption).setOption({
      backgroundColor: 'transparent',
      tooltip: { trigger: 'axis' },
      legend: { data: ['Avg TTFT (ms)', 'Avg Gen Tok/s'], textStyle: { color: '#9ca3af' } },
      grid: { left: 60, right: 30, top: 40, bottom: 40 },
      xAxis: {
        type: 'category',
        data: concurrencies.map(String),
        name: 'Concurrency',
        nameLocation: 'center',
        nameGap: 30,
        axisLabel: { color: '#9ca3af' },
        axisLine: { lineStyle: { color: '#374151' } },
      },
      yAxis: [
        {
          type: 'value',
          name: 'TTFT (ms)',
          axisLabel: { color: '#9ca3af' },
          splitLine: { lineStyle: { color: '#1f2937' } },
          axisLine: { lineStyle: { color: '#374151' } },
        },
        {
          type: 'value',
          name: 'Gen Tok/s',
          axisLabel: { color: '#9ca3af' },
          splitLine: { show: false },
          axisLine: { lineStyle: { color: '#374151' } },
        },
      ],
      series: [
        {
          name: 'Avg TTFT (ms)',
          type: 'line',
          data: avgTtft,
          smooth: true,
          lineStyle: { color: '#f59e0b' },
          itemStyle: { color: '#f59e0b' },
        },
        {
          name: 'Avg Gen Tok/s',
          type: 'line',
          yAxisIndex: 1,
          data: avgGenTps,
          smooth: true,
          lineStyle: { color: '#10b981' },
          itemStyle: { color: '#10b981' },
        },
      ],
    });
  };

  const renderHistoryChart = () => {
    if (!historyChartRef.current || runs.length < 2) return;

    const instance = echarts.getInstanceByDom(historyChartRef.current);
    if (instance) instance.dispose();

    const theme = buildEChartsTheme();
    const completed = runs.filter((r) => r.status === 'completed' && r.aggregate);

    const labels = completed.map((r) => r.id.slice(0, 8));
    const genTpsData = completed.map((r) => (r.aggregate?.avgGenTps as number) ?? 0);
    const ttftData = completed.map((r) => (r.aggregate?.avgTtftMs as number) ?? 0);

    echarts.init(historyChartRef.current, theme as echarts.EChartsCoreOption).setOption({
      backgroundColor: 'transparent',
      tooltip: { trigger: 'axis' },
      legend: { data: ['Gen Tok/s', 'TTFT (ms)'], textStyle: { color: '#9ca3af' } },
      grid: { left: 60, right: 30, top: 40, bottom: 60 },
      xAxis: {
        type: 'category',
        data: labels,
        axisLabel: { color: '#9ca3af', rotate: 45 },
        axisLine: { lineStyle: { color: '#374151' } },
      },
      yAxis: [
        {
          type: 'value',
          name: 'Gen Tok/s',
          axisLabel: { color: '#9ca3af' },
          splitLine: { lineStyle: { color: '#1f2937' } },
          axisLine: { lineStyle: { color: '#374151' } },
        },
        {
          type: 'value',
          name: 'TTFT (ms)',
          axisLabel: { color: '#9ca3af' },
          splitLine: { show: false },
          axisLine: { lineStyle: { color: '#374151' } },
        },
      ],
      series: [
        {
          name: 'Gen Tok/s',
          type: 'line',
          data: genTpsData,
          smooth: true,
          lineStyle: { color: '#10b981' },
          itemStyle: { color: '#10b981' },
        },
        {
          name: 'TTFT (ms)',
          type: 'line',
          yAxisIndex: 1,
          data: ttftData,
          smooth: true,
          lineStyle: { color: '#f59e0b' },
          itemStyle: { color: '#f59e0b' },
        },
      ],
    });
  };

  return (
    <div className="flex flex-col flex-1 min-h-0">
      {/* Sub-nav */}
      <div className="flex gap-1 px-4 pt-2 shrink-0">
        {[
          { id: 'launcher' as const, label: 'Launcher', icon: Play },
          { id: 'history' as const, label: 'History', icon: History },
          { id: 'results' as const, label: 'Results', icon: BarChart3 },
        ].map((tab) => (
          <button
            key={tab.id}
            type="button"
            onClick={() => setView(tab.id)}
            className={cn(
              'flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md transition-colors',
              view === tab.id
                ? 'bg-accent/20 text-accent'
                : 'text-muted-foreground hover:text-foreground'
            )}
          >
            <tab.icon className="size-3" />
            {tab.label}
          </button>
        ))}
      </div>

      {/* Launcher view */}
      {view === 'launcher' && (
        <div className="flex-1 overflow-y-auto px-4 py-3">
          {/* Create suite form */}
          <div className="mb-4 p-4 bg-muted/20 rounded-lg border border-border/30">
            <h3 className="text-sm font-medium mb-3 flex items-center gap-2">
              <Plus className="size-3" />
              New Suite
            </h3>
            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="text-xs text-muted-foreground">Name</label>
                <input
                  type="text"
                  value={suiteName}
                  onChange={(e) => setSuiteName(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                  placeholder="my-bench"
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Provider</label>
                <select
                  value={suiteProvider}
                  onChange={(e) => setSuiteProvider(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                >
                  <option value="">Select host</option>
                  {providerIds.map((pid) => (
                    <option key={pid} value={pid}>{pid}</option>
                  ))}
                </select>
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Model</label>
                <input
                  type="text"
                  value={suiteModel}
                  onChange={(e) => setSuiteModel(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                  placeholder="llama-3.1-8b-q4"
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Repetitions</label>
                <input
                  type="number"
                  min={1}
                  value={suiteRepetitions}
                  onChange={(e) => setSuiteRepetitions(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Prompt Tokens (comma-sep)</label>
                <input
                  type="text"
                  value={suitePromptTokens}
                  onChange={(e) => setSuitePromptTokens(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Gen Tokens (comma-sep)</label>
                <input
                  type="text"
                  value={suiteGenTokens}
                  onChange={(e) => setSuiteGenTokens(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                />
              </div>
              <div>
                <label className="text-xs text-muted-foreground">Concurrency (comma-sep)</label>
                <input
                  type="text"
                  value={suiteConcurrency}
                  onChange={(e) => setSuiteConcurrency(e.target.value)}
                  className="w-full bg-muted/50 border border-border/50 rounded px-2 py-1 text-sm"
                />
              </div>
            </div>
            <div className="mt-2 text-[11px] text-muted-foreground">
              Use comma-separated positive numbers, for example 256,512,1024.
            </div>
            <button
              type="button"
              onClick={createSuite}
              disabled={suiteValidation.reason != null}
              className="mt-2 px-3 py-1.5 bg-accent/20 text-accent rounded text-sm hover:bg-accent/30 disabled:opacity-50 transition-colors"
              title={suiteValidation.reason ?? 'Create suite'}
            >
              Create Suite
            </button>
            {suiteValidation.reason && (
              <div className="mt-1 text-[11px] text-amber-400">{suiteValidation.reason}</div>
            )}
          </div>

          {activeRun && (
            <div className="mb-3 flex items-center justify-between rounded-md border border-accent/20 bg-accent/10 px-3 py-2 text-xs text-accent">
              <span>Bench run in progress</span>
              <span className="font-mono">{activeRun.completedSamples}/{activeRun.totalSamples} samples</span>
            </div>
          )}

          {/* Existing suites */}
          <div className="space-y-2">
            {suites.map((suite) => (
              <div key={suite.id} className="flex items-center justify-between p-3 bg-muted/20 rounded-lg border border-border/30">
                <div>
                  <div className="text-sm font-medium">{suite.name}</div>
                  <div className="text-xs text-muted-foreground">
                    {suite.providerId} / {suite.model}
                    {' '}
                    ({suite.promptTokens.join(',')}pt x {suite.genTokens.join(',')}gt x {suite.concurrency.join(',')}c)
                  </div>
                </div>
                <button
                  type="button"
                  onClick={() => runBench(suite.id)}
                  disabled={loading || running}
                  className="flex items-center gap-1.5 px-3 py-1.5 bg-accent/20 text-accent rounded text-xs hover:bg-accent/30 disabled:opacity-50 transition-colors"
                >
                  {loading || running ? <Loader2 className="size-3 animate-spin" /> : <Play className="size-3" />}
                  Run
                </button>
              </div>
            ))}
          </div>

          {recentTraffic && (
            <div className="mt-3 flex items-center gap-2 px-3 py-2 bg-yellow-500/10 border border-yellow-500/20 rounded text-xs text-yellow-400">
              <AlertTriangle className="size-3 shrink-0" />
              Target host has recent traffic. Bench results may be affected.
            </div>
          )}
        </div>
      )}

      {/* History view */}
      {view === 'history' && (
        <div className="flex-1 flex flex-col min-h-0 overflow-hidden">
          {runs.length >= 2 && (
            <div ref={historyChartRef} className="h-[200px] shrink-0" />
          )}
          <div className="flex-1 overflow-y-auto px-4 py-3">
            <div className="space-y-2">
              {runs.map((run) => {
                const suite = suites.find((s) => s.id === run.suiteId);
                const flag = run.regressionFlag;

                return (
                  <div
                    key={run.id}
                    onClick={() => loadRunDetails(run.id)}
                    className="flex items-center justify-between p-3 bg-muted/20 rounded-lg border border-border/30 cursor-pointer hover:bg-muted/30 transition-colors"
                  >
                    <div>
                      <div className="text-sm font-medium flex items-center gap-2">
                        {run.id.slice(0, 12)}
                        <span className={cn(
                          'px-1.5 py-0.5 rounded text-[10px]',
                          run.status === 'completed' ? 'bg-green-500/20 text-green-400' :
                          run.status === 'failed' ? 'bg-red-500/20 text-red-400' :
                          'bg-yellow-500/20 text-yellow-400'
                        )}>
                          {run.status}
                        </span>
                        {flag === 'regression' && (
                          <span className="flex items-center gap-0.5 text-red-400">
                            <TrendingDown className="size-3" />
                          </span>
                        )}
                        {flag === 'improvement' && (
                          <span className="flex items-center gap-0.5 text-green-400">
                            <TrendingUp className="size-3" />
                          </span>
                        )}
                      </div>
                      <div className="text-xs text-muted-foreground">
                        {suite?.name} - {run.completedSamples}/{run.totalSamples} samples
                        {run.concurrentForeignRequests > 0 && (
                          <span className="text-yellow-400 ml-1">
                            ({run.concurrentForeignRequests} foreign reqs)
                          </span>
                        )}
                      </div>
                    </div>
                    {run.aggregate && (
                      <div className="text-right text-xs text-muted-foreground">
                        {run.aggregate.avgGenTps != null && (
                          <div>{(run.aggregate.avgGenTps as number).toFixed(1)} tok/s</div>
                        )}
                        {run.aggregate.avgTtftMs != null && (
                          <div>{(run.aggregate.avgTtftMs as number).toFixed(0)}ms TTFT</div>
                        )}
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      )}

      {/* Results view */}
      {view === 'results' && (
        <div className="flex-1 flex flex-col min-h-0 overflow-hidden">
          {selectedRun ? (
            <>
              <div ref={chartRef} className="h-[250px] shrink-0" />
              <div className="flex-1 overflow-y-auto px-4 py-3">
                <div className="text-xs text-muted-foreground mb-2">
                  {selectedRun.id.slice(0, 16)} - {selectedRun.completedSamples}/{selectedRun.totalSamples} samples
                  {selectedRun.concurrentForeignRequests > 0 && (
                    <span className="ml-2 text-yellow-400">
                      ({selectedRun.concurrentForeignRequests} concurrent foreign requests)
                    </span>
                  )}
                </div>
                <div className="overflow-x-auto">
                  <table className="w-full text-xs">
                    <thead>
                      <tr className="text-muted-foreground border-b border-border/30">
                        <th className="text-left py-1 px-2">PT</th>
                        <th className="text-left py-1 px-2">GT</th>
                        <th className="text-left py-1 px-2">Conc</th>
                        <th className="text-left py-1 px-2">Rep</th>
                        <th className="text-right py-1 px-2">TTFT</th>
                        <th className="text-right py-1 px-2">Total</th>
                        <th className="text-right py-1 px-2">Prompt/s</th>
                        <th className="text-right py-1 px-2">Gen/s</th>
                        <th className="text-right py-1 px-2">Cache</th>
                      </tr>
                    </thead>
                    <tbody>
                      {samples.map((s) => (
                        <tr key={s.id} className="border-b border-border/20">
                          <td className="py-1 px-2">{s.promptTokens}</td>
                          <td className="py-1 px-2">{s.genTokens}</td>
                          <td className="py-1 px-2">{s.concurrency}</td>
                          <td className="py-1 px-2">{s.repetition}</td>
                          <td className="py-1 px-2 text-right">{s.ttftMs?.toFixed(0) ?? '-'}</td>
                          <td className="py-1 px-2 text-right">{s.totalMs?.toFixed(0) ?? '-'}</td>
                          <td className="py-1 px-2 text-right">{s.promptTps?.toFixed(1) ?? '-'}</td>
                          <td className="py-1 px-2 text-right">{s.genTps?.toFixed(1) ?? '-'}</td>
                          <td className="py-1 px-2 text-right">{s.cacheN ?? '-'}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              </div>
            </>
          ) : (
            <div className="flex items-center justify-center flex-1 text-muted-foreground text-sm">
              Select a run from History to view results
            </div>
          )}
        </div>
      )}
    </div>
  );
}
