'use client';

import Link from 'next/link';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useEffect, useMemo, useState, type ReactNode } from 'react';
import {
  getEvalRunDetail,
  getEvalRunStatus,
  getEvalRunSummary,
  listEvalRuns,
  type EvalRunDetail,
  type EvalRunListRow,
  type EvalRunStatusPayload,
  type EvalRunSummaryPayload,
} from '@/lib/admin-eval-runs';
import { useTranslation } from '@/lib/i18n';

type Filters = {
  trigger_mode: string;
  execution_status: string;
  model_family: string;
  resolved_model: string;
};

interface LineSeries {
  label: string;
  color: string;
  data: (number | null)[];
}

type TrendPoint = {
  runId: string;
  label: string;
  avgScore: number | null;
  avgCaseDurationSeconds: number | null;
  avgInputTokens: number | null;
  avgOutputTokens: number | null;
  avgReasoningTokens: number | null;
  avgCachedTokens: number | null;
  avgTotalTokens: number | null;
  bucketAverages: Record<string, number | null>;
};

const INITIAL_SUMMARY: EvalRunSummaryPayload = {
  total_runs: 0,
  active_runs: 0,
  completed_runs: 0,
  invalid_runs: 0,
  case_count: 0,
  passed_count: 0,
  failed_count: 0,
  invalid_count: 0,
  latest_run_id: '',
  latest_run_started_at: '',
  latest_run_status: '',
  latest_run_trigger_mode: '',
  active_run_ids: [],
};

const INITIAL_STATUS: EvalRunStatusPayload = {
  running: false,
  active_run_count: 0,
  active_runs: [],
};

const SCORE_BUCKETS = [
  'workflow',
  'evidence_collection',
  'critical_evidence',
  'evidence_routing',
  'diagnosis',
] as const;

const LEGACY_CLAUDE_RESOLVED_MODEL = 'amazon-bedrock/claude-sonnet-bedrock';
const DEFAULT_MODEL_FAMILY = 'claude';
const FIXED_RESOLVED_MODELS = [
  'chat/claude-standard',
  'chat/claude-standard/high',
  'chat/claude-pro/high',
  'openai/gpt-5.2',
] as const;

function normalizeResolvedModel(value: string | null): string {
  if (!value) return '';
  if (value === LEGACY_CLAUDE_RESOLVED_MODEL) return 'chat/claude-standard';
  return value;
}

function filtersFromSearchParams(searchParams: URLSearchParams): Filters {
  const resolvedModel = normalizeResolvedModel(searchParams.get('resolved_model'));
  return {
    trigger_mode: searchParams.get('trigger_mode') || '',
    execution_status: searchParams.get('execution_status') || '',
    model_family: searchParams.get('model_family') || (resolvedModel ? '' : DEFAULT_MODEL_FAMILY),
    resolved_model: resolvedModel,
  };
}

function formatDateTime(value: string | null | undefined): string {
  if (!value) return '—';
  const date = new Date(value);
  return Number.isNaN(date.getTime()) ? value : date.toLocaleString();
}

function formatShortDate(value: string): string {
  if (!value) return '—';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value.slice(0, 10);
  return `${date.getMonth() + 1}/${date.getDate()}`;
}

function prettyLabel(value: string): string {
  if (!value) return '—';
  return value.replace(/_/g, ' ');
}

function formatRunTotalScore(run: EvalRunListRow): string {
  const totalScore = run.score_summary?.total_score;
  const maxScore = run.score_summary?.max_score;
  if (typeof totalScore !== 'number' || typeof maxScore !== 'number' || maxScore <= 0) {
    return '—';
  }
  return `${Math.round(totalScore)}/${Math.round(maxScore)}`;
}

function durationSeconds(startedAt: string | null | undefined, finishedAt: string | null | undefined): number | null {
  if (!startedAt || !finishedAt) return null;
  const start = new Date(startedAt).getTime();
  const end = new Date(finishedAt).getTime();
  if (Number.isNaN(start) || Number.isNaN(end) || end < start) return null;
  return (end - start) / 1000;
}

function StatusBadge({ value }: { value: string }) {
  const normalized = value.toLowerCase();
  let background = '#eef2ff';
  let color = '#4338ca';
  if (normalized === 'completed' || normalized === 'pass' || normalized === 'compared') {
    background = '#dcfce7';
    color = '#166534';
  } else if (normalized === 'running' || normalized === 'pending') {
    background = '#dbeafe';
    color = '#1d4ed8';
  } else if (normalized === 'failed' || normalized === 'invalid') {
    background = '#fee2e2';
    color = '#b91c1c';
  } else if (normalized === 'skipped') {
    background = '#fef3c7';
    color = '#92400e';
  }
  return (
    <span
      style={{
        display: 'inline-flex',
        alignItems: 'center',
        padding: '4px 10px',
        borderRadius: 999,
        background,
        color,
        fontSize: 12,
        fontWeight: 700,
        textTransform: 'capitalize',
      }}
    >
      {prettyLabel(value)}
    </span>
  );
}

function KpiCard({ label, value, hint }: { label: string; value: string; hint: string }) {
  return (
    <div
      style={{
        background: '#fff',
        borderRadius: 14,
        border: '1px solid #ececf4',
        boxShadow: '0 2px 10px rgba(92,95,188,0.06)',
        padding: '16px 18px',
      }}
    >
      <div style={{ fontSize: 11, fontWeight: 700, color: '#9ca3af', letterSpacing: '0.06em', textTransform: 'uppercase' }}>
        {label}
      </div>
      <div style={{ marginTop: 8, fontSize: 28, fontWeight: 700, color: '#1f2937' }}>{value}</div>
      <div style={{ marginTop: 6, fontSize: 12, color: '#6b7280' }}>{hint}</div>
    </div>
  );
}

function SectionCard({ title, subtitle, children }: { title: string; subtitle?: string; children: ReactNode }) {
  return (
    <div
      style={{
        background: '#fff',
        borderRadius: 14,
        border: '1px solid #ececf4',
        boxShadow: '0 2px 10px rgba(92,95,188,0.06)',
        padding: '18px 20px',
      }}
    >
      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 16, fontWeight: 700, color: '#1f2937' }}>{title}</div>
        {subtitle ? <div style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{subtitle}</div> : null}
      </div>
      {children}
    </div>
  );
}

function MultiLineChart({ series, labels, height = 220, maxY }: { series: LineSeries[]; labels: string[]; height?: number; maxY?: number }) {
  const { t } = useTranslation();
  if (!labels.length) {
    return (
      <div style={{ textAlign: 'center', padding: '32px 0', color: '#9ca3af', fontSize: 13 }}>
        {t('adminEvalRuns.needTwoRuns')}
      </div>
    );
  }

  const W = 480;
  const H = height;
  const padTop = 16;
  const padBottom = 24;
  const padLeft = 8;
  const padRight = 20;
  const yLabelWidth = 38;
  const chartW = W - padLeft - padRight;
  const chartH = H - padTop - padBottom;

  const allValues = series.flatMap((item) => item.data.filter((value): value is number => value !== null));
  const rawMax = Math.max(...allValues, 0);
  const rawMin = Math.min(...allValues, 0);
  const absExtent = Math.max(Math.abs(rawMax), Math.abs(rawMin), maxY ?? 0, 1);
  const paddedExtent = absExtent * 1.15;
  const yMax = maxY != null ? Math.max(maxY, rawMax, 1) : paddedExtent;
  const yMin = maxY != null ? Math.min(-maxY, rawMin, -1) : -paddedExtent;
  const range = yMax - yMin || 1;
  const tickCount = 4;
  const ticks = Array.from({ length: tickCount + 1 }, (_, i) => {
    const val = yMin + (range * i) / tickCount;
    const y = padTop + chartH - (i / tickCount) * chartH;
    return { val, y };
  });
  const zeroY = padTop + chartH - ((0 - yMin) / range) * chartH;
  const hasAnyPoints = series.some((item) => item.data.some((value) => value !== null));

  if (!hasAnyPoints) {
    return (
      <div style={{ textAlign: 'center', padding: '32px 0', color: '#9ca3af', fontSize: 13 }}>
        {t('adminEvalRuns.noTrendData')}
      </div>
    );
  }

  return (
    <div>
      <div style={{ display: 'flex' }}>
        <div style={{ width: yLabelWidth, flexShrink: 0, position: 'relative', height: H - padBottom }}>
          {ticks.map((tick, index) => (
            <span
              key={index}
              style={{
                position: 'absolute',
                right: 4,
                top: tick.y,
                transform: 'translateY(-50%)',
                fontSize: 10,
                color: '#9ca3af',
                lineHeight: 1,
              }}
            >
              {Math.round(tick.val * 10) / 10}
            </span>
          ))}
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="none" style={{ display: 'block' }}>
            {ticks.map((tick, index) => (
              <line
                key={index}
                x1={padLeft}
                y1={tick.y}
                x2={W - padRight}
                y2={tick.y}
                stroke={Math.abs(tick.val) < 1e-9 ? '#cbd5e1' : '#eef2f7'}
                strokeWidth={Math.abs(tick.val) < 1e-9 ? 1.25 : 0.75}
              />
            ))}
            <line x1={padLeft} y1={zeroY} x2={W - padRight} y2={zeroY} stroke="#94a3b8" strokeWidth={1.25} strokeDasharray="4 3" />
            {series.map((item) => {
              const points = item.data
                .map((value, index) => value !== null ? {
                  x: labels.length === 1 ? padLeft + chartW / 2 : padLeft + (index / (labels.length - 1)) * chartW,
                  y: padTop + chartH - ((value - yMin) / range) * chartH,
                } : null)
                .filter((point): point is { x: number; y: number } => point !== null);
              return (
                <g key={item.label}>
                  {points.length >= 2 ? (
                    <path
                      d={points.map((point, index) => `${index === 0 ? 'M' : 'L'}${point.x},${point.y}`).join(' ')}
                      fill="none"
                      stroke={item.color}
                      strokeWidth={2}
                      strokeLinecap="round"
                      strokeLinejoin="round"
                    />
                  ) : null}
                  {points.map((point, index) => (
                    <circle key={index} cx={point.x} cy={point.y} r={3} fill={item.color} />
                  ))}
                </g>
              );
            })}
          </svg>
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, marginTop: 6 }}>
            {labels.map((label, index) => (
              <span key={`${label}-${index}`} style={{ fontSize: 10, color: '#9ca3af', flex: 1, textAlign: index === 0 ? 'left' : index === labels.length - 1 ? 'right' : 'center' }}>
                {label}
              </span>
            ))}
          </div>
        </div>
      </div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, justifyContent: 'center', marginTop: 10 }}>
        {series.map((item) => (
          <div key={item.label} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, color: '#374151' }}>
            <span style={{ width: 14, height: 2, background: item.color, display: 'inline-block' }} />
            {item.label}
          </div>
        ))}
      </div>
    </div>
  );
}

export default function AdminEvalRunsPage() {
  const { t } = useTranslation();
  const router = useRouter();
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const [filters, setFilters] = useState<Filters>(() => filtersFromSearchParams(new URLSearchParams(searchParams.toString())));
  const [runs, setRuns] = useState<EvalRunListRow[]>([]);
  const [modelOptionRuns, setModelOptionRuns] = useState<EvalRunListRow[]>([]);
  const [runDetails, setRunDetails] = useState<Record<string, EvalRunDetail>>({});
  const [summary, setSummary] = useState<EvalRunSummaryPayload>(INITIAL_SUMMARY);
  const [status, setStatus] = useState<EvalRunStatusPayload>(INITIAL_STATUS);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');

  useEffect(() => {
    const nextFilters = filtersFromSearchParams(new URLSearchParams(searchParams.toString()));
    setFilters((prev) => (
      prev.trigger_mode === nextFilters.trigger_mode
      && prev.execution_status === nextFilters.execution_status
      && prev.model_family === nextFilters.model_family
      && prev.resolved_model === nextFilters.resolved_model
    ) ? prev : nextFilters);
  }, [searchParams]);

  useEffect(() => {
    const params = new URLSearchParams(searchParams.toString());
    const currentFilters = filtersFromSearchParams(params);
    if (
      currentFilters.trigger_mode === filters.trigger_mode
      && currentFilters.execution_status === filters.execution_status
      && currentFilters.model_family === filters.model_family
      && currentFilters.resolved_model === filters.resolved_model
    ) {
      return;
    }
    if (filters.trigger_mode) params.set('trigger_mode', filters.trigger_mode);
    else params.delete('trigger_mode');
    if (filters.execution_status) params.set('execution_status', filters.execution_status);
    else params.delete('execution_status');
    if (filters.model_family) params.set('model_family', filters.model_family);
    else params.delete('model_family');
    if (filters.resolved_model) params.set('resolved_model', filters.resolved_model);
    else params.delete('resolved_model');
    const query = params.toString();
    router.replace(query ? `${pathname}?${query}` : pathname, { scroll: false });
  }, [filters, pathname, router, searchParams]);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      setLoading(true);
      setError('');
      try {
        const query = {
          limit: 50,
          trigger_mode: filters.trigger_mode || undefined,
          execution_status: filters.execution_status || undefined,
          model_family: filters.model_family || undefined,
          resolved_model: filters.resolved_model || undefined,
        };
        const [nextRuns, nextSummary, nextStatus] = await Promise.all([
          listEvalRuns(query),
          getEvalRunSummary(query),
          getEvalRunStatus(query),
        ]);
        if (cancelled) return;
        setRuns(nextRuns);
        setSummary(nextSummary);
        setStatus(nextStatus);
      } catch (err) {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : t('adminEvalRuns.loadError'));
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    load();
    return () => {
      cancelled = true;
    };
  }, [filters, t]);

  useEffect(() => {
    let cancelled = false;
    async function loadModelOptions() {
      try {
        const nextRuns = await listEvalRuns({ limit: 200 });
        if (!cancelled) {
          setModelOptionRuns(nextRuns);
        }
      } catch {
        if (!cancelled) {
          setModelOptionRuns([]);
        }
      }
    }
    loadModelOptions();
    return () => {
      cancelled = true;
    };
  }, []);

  const trendRuns = useMemo(
    () => runs.filter((run) => run.trigger_mode !== 'manual_case').slice(0, 12),
    [runs]
  );

  useEffect(() => {
    let cancelled = false;
    async function loadDetails() {
      if (!trendRuns.length) {
        setRunDetails({});
        return;
      }
      try {
        const details = await Promise.allSettled(trendRuns.map((run) => getEvalRunDetail(run.id)));
        if (cancelled) return;
        const next: Record<string, EvalRunDetail> = {};
        for (const detail of details) {
          if (detail.status === 'fulfilled') {
            next[detail.value.id] = detail.value;
          }
        }
        setRunDetails(next);
      } catch {
        if (!cancelled) setRunDetails({});
      }
    }
    loadDetails();
    return () => {
      cancelled = true;
    };
  }, [trendRuns]);

  const resolvedModelOptions = useMemo(() => {
    const values = new Set<string>(FIXED_RESOLVED_MODELS);
    for (const run of modelOptionRuns) {
      if (run.resolved_model) values.add(run.resolved_model);
    }
    return Array.from(values).sort();
  }, [modelOptionRuns]);

  const trendPoints = useMemo<TrendPoint[]>(() => {
    return trendRuns.map((run) => {
      const detail = runDetails[run.id];
      if (!detail) {
        return {
          runId: run.id,
          label: formatShortDate(run.started_at),
          avgScore: null,
          avgCaseDurationSeconds: null,
          avgInputTokens: null,
          avgOutputTokens: null,
          avgReasoningTokens: null,
          avgCachedTokens: null,
          avgTotalTokens: null,
          bucketAverages: Object.fromEntries(SCORE_BUCKETS.map((bucket) => [bucket, null])),
        };
      }
      const diff = detail.baseline_diff_metrics;
      const bucketAverages = Object.fromEntries(
        SCORE_BUCKETS.map((bucket) => [bucket, diff?.bucket_avg_diffs?.[bucket] ?? null])
      ) as Record<string, number | null>;

      return {
        runId: run.id,
        label: formatShortDate(run.started_at),
        avgScore: diff?.avg_score_diff ?? null,
        avgCaseDurationSeconds: diff?.avg_case_duration_diff_seconds ?? null,
        avgInputTokens: diff?.avg_token_diff?.input_tokens ?? null,
        avgOutputTokens: diff?.avg_token_diff?.output_tokens ?? null,
        avgReasoningTokens: diff?.avg_token_diff?.reasoning_tokens ?? null,
        avgCachedTokens: diff?.avg_token_diff?.cached_tokens ?? null,
        avgTotalTokens: diff?.avg_token_diff?.total_tokens ?? null,
        bucketAverages,
      };
    }).reverse();
  }, [runDetails, trendRuns]);

  const scoreSeries = useMemo<LineSeries[]>(() => [
    { label: t('adminEvalRuns.trendAvgScoreDiff'), color: '#4f46e5', data: trendPoints.map((point) => point.avgScore) },
    { label: t('adminEvalRuns.trendWorkflowDiff'), color: '#0f766e', data: trendPoints.map((point) => point.bucketAverages.workflow ?? null) },
    { label: t('adminEvalRuns.trendEvidenceCollectionDiff'), color: '#0891b2', data: trendPoints.map((point) => point.bucketAverages.evidence_collection ?? null) },
    { label: t('adminEvalRuns.trendCriticalEvidenceDiff'), color: '#d97706', data: trendPoints.map((point) => point.bucketAverages.critical_evidence ?? null) },
    { label: t('adminEvalRuns.trendEvidenceRoutingDiff'), color: '#be123c', data: trendPoints.map((point) => point.bucketAverages.evidence_routing ?? null) },
    { label: t('adminEvalRuns.trendDiagnosisDiff'), color: '#dc2626', data: trendPoints.map((point) => point.bucketAverages.diagnosis ?? null) },
  ], [t, trendPoints]);

  const timingSeries = useMemo<LineSeries[]>(() => [
    { label: t('adminEvalRuns.trendAvgCaseDurationDiffSeconds'), color: '#2563eb', data: trendPoints.map((point) => point.avgCaseDurationSeconds) },
  ], [t, trendPoints]);

  const tokenSeries = useMemo<LineSeries[]>(() => [
    { label: t('adminEvalRuns.trendAvgInputTokensDiff'), color: '#7c3aed', data: trendPoints.map((point) => point.avgInputTokens) },
    { label: t('adminEvalRuns.trendAvgOutputTokensDiff'), color: '#db2777', data: trendPoints.map((point) => point.avgOutputTokens) },
    { label: t('adminEvalRuns.trendAvgReasoningTokensDiff'), color: '#ea580c', data: trendPoints.map((point) => point.avgReasoningTokens) },
    { label: t('adminEvalRuns.trendAvgCachedTokensDiff'), color: '#0891b2', data: trendPoints.map((point) => point.avgCachedTokens) },
    { label: t('adminEvalRuns.trendAvgTotalTokensDiff'), color: '#1d4ed8', data: trendPoints.map((point) => point.avgTotalTokens) },
  ], [t, trendPoints]);
  const currentQuery = searchParams.toString();

  return (
    <div style={{ paddingTop: 8 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', gap: 16, alignItems: 'flex-start', marginBottom: 24 }}>
        <div>
          <h1 style={{ margin: 0, fontSize: 24, fontWeight: 700, color: '#1a1a2e' }}>{t('adminEvalRuns.title')}</h1>
          <p style={{ margin: '8px 0 0', fontSize: 14, lineHeight: 1.6, color: '#6b7280', maxWidth: 760 }}>
            {t('adminEvalRuns.subtitle')}
          </p>
        </div>
      </div>

      {status.running && (
        <div
          style={{
            marginBottom: 18,
            padding: '14px 16px',
            borderRadius: 12,
            background: '#eff6ff',
            border: '1px solid #bfdbfe',
            color: '#1e3a8a',
          }}
        >
          <div style={{ fontSize: 13, fontWeight: 700 }}>{t('adminEvalRuns.activeBannerTitle', { count: status.active_run_count })}</div>
          <div style={{ marginTop: 6, fontSize: 13 }}>
            {status.active_runs
              .map((run) => `${run.suite_id} · ${run.resolved_model || t('adminEvalRuns.unknownRuntime')}`)
              .join(' | ')}
          </div>
        </div>
      )}

      {error && (
        <div
          style={{
            marginBottom: 18,
            padding: '14px 16px',
            borderRadius: 12,
            background: '#fef2f2',
            border: '1px solid #fecaca',
            color: '#991b1b',
            fontSize: 13,
          }}
        >
          {error}
        </div>
      )}

      <div
        style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))',
          gap: 12,
          marginBottom: 20,
        }}
      >
        <KpiCard label={t('adminEvalRuns.kpiTotalRuns')} value={String(summary.total_runs)} hint={t('adminEvalRuns.kpiTotalRunsHint')} />
        <KpiCard label={t('adminEvalRuns.kpiActiveRuns')} value={String(summary.active_runs)} hint={t('adminEvalRuns.kpiActiveRunsHint')} />
        <KpiCard label={t('adminEvalRuns.kpiCompletedRuns')} value={String(summary.completed_runs)} hint={t('adminEvalRuns.kpiCompletedRunsHint')} />
        <KpiCard label={t('adminEvalRuns.kpiPassRate')} value={summary.case_count > 0 ? `${Math.round((summary.passed_count / summary.case_count) * 100)}%` : '—'} hint={t('adminEvalRuns.kpiPassRateHint')} />
        <KpiCard label={t('adminEvalRuns.kpiLatestRun')} value={summary.latest_run_status ? prettyLabel(summary.latest_run_status) : '—'} hint={summary.latest_run_started_at ? formatDateTime(summary.latest_run_started_at) : t('adminEvalRuns.noRunsYet')} />
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(340px, 1fr))', gap: 16, marginBottom: 18 }}>
        <SectionCard title={t('adminEvalRuns.scoreTrendTitle')} subtitle={t('adminEvalRuns.scoreTrendSubtitle')}>
          <MultiLineChart series={scoreSeries} labels={trendPoints.map((point) => point.label)} />
        </SectionCard>
        <SectionCard title={t('adminEvalRuns.timingTrendTitle')} subtitle={t('adminEvalRuns.timingTrendSubtitle')}>
          <MultiLineChart series={timingSeries} labels={trendPoints.map((point) => point.label)} />
        </SectionCard>
        <SectionCard title={t('adminEvalRuns.tokenTrendTitle')} subtitle={t('adminEvalRuns.tokenTrendSubtitle')}>
          <MultiLineChart series={tokenSeries} labels={trendPoints.map((point) => point.label)} />
        </SectionCard>
      </div>

      <div
        style={{
          background: '#fff',
          borderRadius: 14,
          border: '1px solid #ececf4',
          boxShadow: '0 2px 10px rgba(92,95,188,0.06)',
          padding: '16px 18px',
          marginBottom: 18,
        }}
      >
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 12 }}>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#6b7280' }}>
            {t('adminEvalRuns.filterTriggerMode')}
            <select
              value={filters.trigger_mode}
              onChange={(e) => setFilters((prev) => ({ ...prev, trigger_mode: e.target.value }))}
              style={{ borderRadius: 10, border: '1px solid #d1d5db', padding: '10px 12px', fontSize: 14 }}
            >
              <option value="">{t('adminEvalRuns.filterAny')}</option>
              <option value="scheduled">{t('adminEvalRuns.filterScheduled')}</option>
              <option value="manual_suite">{t('adminEvalRuns.filterManualSuite')}</option>
              <option value="manual_case">{t('adminEvalRuns.filterManualCase')}</option>
              <option value="rerun_failed">{t('adminEvalRuns.filterRerunFailed')}</option>
            </select>
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#6b7280' }}>
            {t('adminEvalRuns.filterExecutionStatus')}
            <select
              value={filters.execution_status}
              onChange={(e) => setFilters((prev) => ({ ...prev, execution_status: e.target.value }))}
              style={{ borderRadius: 10, border: '1px solid #d1d5db', padding: '10px 12px', fontSize: 14 }}
            >
              <option value="">{t('adminEvalRuns.filterAny')}</option>
              <option value="running">{t('adminEvalRuns.statusRunning')}</option>
              <option value="completed">{t('adminEvalRuns.statusCompleted')}</option>
              <option value="failed">{t('adminEvalRuns.statusFailed')}</option>
              <option value="invalid">{t('adminEvalRuns.statusInvalid')}</option>
            </select>
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#6b7280' }}>
            {t('adminEvalRuns.filterResolvedModel')}
            <select
              value={filters.resolved_model ? `model:${filters.resolved_model}` : filters.model_family ? `family:${filters.model_family}` : ''}
              onChange={(e) => {
                const value = e.target.value;
                if (!value) {
                  setFilters((prev) => ({ ...prev, model_family: '', resolved_model: '' }));
                  return;
                }
                if (value.startsWith('family:')) {
                  setFilters((prev) => ({ ...prev, model_family: value.slice('family:'.length), resolved_model: '' }));
                  return;
                }
                if (value.startsWith('model:')) {
                  setFilters((prev) => ({ ...prev, model_family: '', resolved_model: value.slice('model:'.length) }));
                }
              }}
              style={{ borderRadius: 10, border: '1px solid #d1d5db', padding: '10px 12px', fontSize: 14 }}
            >
              <option value="family:claude">{t('adminEvalRuns.filterClaudeFamily')}</option>
              <option value="">{t('adminEvalRuns.filterAny')}</option>
              {resolvedModelOptions.map((option) => (
                <option key={option} value={`model:${option}`}>
                  {option}
                </option>
              ))}
            </select>
          </label>
        </div>
      </div>

      <div
        style={{
          background: '#fff',
          borderRadius: 14,
          border: '1px solid #ececf4',
          boxShadow: '0 2px 10px rgba(92,95,188,0.06)',
          overflow: 'hidden',
        }}
      >
        <div style={{ padding: '16px 18px', borderBottom: '1px solid #eef2f7', display: 'flex', justifyContent: 'space-between', gap: 12 }}>
          <div>
            <div style={{ fontSize: 15, fontWeight: 700, color: '#1f2937' }}>{t('adminEvalRuns.tableTitle')}</div>
            <div style={{ marginTop: 4, fontSize: 12, color: '#6b7280' }}>{t('adminEvalRuns.tableSubtitle', { count: runs.length })}</div>
          </div>
          <button
            type="button"
            onClick={() => setFilters((prev) => ({ ...prev }))}
            style={{
              borderRadius: 10,
              border: '1px solid #d1d5db',
              background: '#fff',
              padding: '8px 12px',
              fontSize: 13,
              fontWeight: 600,
              cursor: 'pointer',
            }}
          >
            {loading ? t('common.loading') : t('common.refresh')}
          </button>
        </div>

        {runs.length === 0 && !loading ? (
          <div style={{ padding: 28, color: '#6b7280', fontSize: 14 }}>{t('adminEvalRuns.empty')}</div>
        ) : (
          <div style={{ overflowX: 'auto' }}>
            <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 1200 }}>
              <thead>
                <tr style={{ background: '#f8fafc' }}>
                  {[
                    t('adminEvalRuns.colRun'),
                    t('adminEvalRuns.colSuite'),
                    t('adminEvalRuns.colTriggerMode'),
                    t('adminEvalRuns.colExecutionStatus'),
                    t('adminEvalRuns.colComparisonStatus'),
                    t('adminEvalRuns.colResolvedModel'),
                    t('adminEvalRuns.colCases'),
                    t('adminEvalRuns.colResults'),
                    t('adminEvalRuns.colTotalScore'),
                    t('adminEvalRuns.colStartedAt'),
                    t('adminEvalRuns.colFinishedAt'),
                  ].map((label) => (
                    <th key={label} style={{ padding: '12px 14px', fontSize: 12, textAlign: 'left', color: '#6b7280', borderBottom: '1px solid #e5e7eb' }}>
                      {label}
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody>
                {runs.map((run) => (
                  <tr key={run.id}>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>
                      <Link href={`/admin/evaluations/runs/${encodeURIComponent(run.id)}${currentQuery ? `?${currentQuery}` : ''}`} style={{ color: '#4338ca', textDecoration: 'none', fontWeight: 600 }}>
                        {run.id}
                      </Link>
                    </td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>{run.suite_id}</td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>{prettyLabel(run.trigger_mode)}</td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}><StatusBadge value={run.execution_status} /></td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}><StatusBadge value={run.comparison_status} /></td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13, maxWidth: 260 }}>{run.resolved_model || '—'}</td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>{run.case_count}</td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>
                      {run.passed_count}/{run.failed_count}/{run.invalid_count}
                    </td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13, fontWeight: 600, color: '#1f2937' }}>
                      {formatRunTotalScore(run)}
                    </td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>{formatDateTime(run.started_at)}</td>
                    <td style={{ padding: '12px 14px', borderBottom: '1px solid #f1f5f9', fontSize: 13 }}>{formatDateTime(run.finished_at)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}
