export type Locale = 'en' | 'zh'

interface Dict {
  [key: string]: string | Dict
}

const en: Dict = {
  nav: {
    dashboard: 'Dashboard',
    eval: 'Evaluation',
    perf: 'Performance',
    benchmarks: 'Benchmarks',
    reports: 'Reports',
  },
  single: {
    selectReport: 'Select Report',
    taskConfig: 'Task Config',
    datasetsOverview: 'Datasets Overview',
    datasetComponents: 'Dataset Components',
    datasetScores: 'Dataset Scores',
    reportAnalysis: 'Report Intelligent Analysis',
    datasetScoresTable: 'Dataset Scores Table',
    datasetDetails: 'Dataset Details',
    selectDataset: 'Select Dataset',
    modelPrediction: 'Model Prediction',
    selectSubset: 'Select Subset',
    answerMode: 'Answer Mode',
    page: 'Page',
    scoreThreshold: 'Score Threshold',
    summaryStats: 'Summary Statistics',
    avgScore: 'Average Score',
    bestDataset: 'Best Dataset',
    weakestDataset: 'Weakest Dataset',
    totalSamples: 'Total Samples',
    radarChart: 'Score Radar Chart',
    scoreDistribution: 'Score Distribution',
    noScoreData: 'No score data available',
    samples: 'samples',
  },
  multi: {
    selectReports: 'Select Reports',
    modelsOverview: 'Models Overview',
    modelRadar: 'Model Comparison Radar',
    modelScores: 'Model Comparison Scores',
    modelComparisonDetails: 'Model Comparison Details',
    selectModelA: 'Select Model A',
    selectModelB: 'Select Model B',
    selectDataset: 'Select Dataset',
    modelPredictions: 'Model Predictions',
    selectSubset: 'Select Subset',
    answerMode: 'Answer Mode',
    scoreThreshold: 'Score Threshold',
    comparisonCounts: 'Comparison Counts',
    page: 'Page',
    input: 'Input',
    goldAnswer: 'Gold Answer',
    score: 'Score',
    normalizedScore: 'Normalized Score',
    prediction: 'Prediction',
    generated: 'Generated',
    groupedBarChart: 'Dataset Score Comparison',
    noCommonDatasets: 'No common datasets across models',
  },
  eval: {
    title: 'Model Evaluation',
    config: 'Evaluation Config',
    datasets: 'Datasets',
    limit: 'Limit',
    batchSize: 'Batch Size',
    moreParams: 'More Parameters',
    repeats: 'Repeats',
    timeout: 'Timeout (s)',
    stream: 'Stream Output',
    temperature: 'Temperature',
    topP: 'Top P',
    maxTokens: 'Max Tokens',
    topK: 'Top K',
    datasetArgs: 'Dataset Args (JSON)',
    startEval: 'Start Evaluation',
    status: 'Status & Logs',
    ready: 'Status: Ready',
    modelName: 'Model Name',
    apiUrl: 'Model API URL',
    apiKey: 'Model API Key',
  },
  perf: {
    title: 'Performance Testing',
    config: 'Performance Config',
    apiType: 'API Type',
    parallel: 'Concurrency (comma-separated)',
    number: 'Total Requests (comma-separated)',
    rate: 'Rate Limit (req/s)',
    maxTokens: 'Max Tokens',
    minTokens: 'Min Tokens',
    dataset: 'Test Dataset',
    maxPromptLen: 'Max Prompt Length',
    minPromptLen: 'Min Prompt Length',
    startPerf: 'Start Performance Test',
    status: 'Status & Logs',
    ready: 'Status: Ready',
  },
  benchmarks: {
    title: 'Benchmark Catalog',
    all: 'All',
    text: 'Text (LLM)',
    multimodal: 'Multimodal (VLM)',
    noDescription: 'No description available',
    search: 'Search benchmarks...',
    use: 'Use',
    useDescription: 'Start evaluation with this benchmark',
    totalCount: '${n} benchmarks',
    filterByTag: 'Filter by tag',
    subsets: 'Subsets',
    samples: 'Samples',
    shots: '${n}-shot',
    noResults: 'No matching benchmarks found',
    clearFilters: 'Clear filters',
    showing: 'Showing ${n} of ${total}',
  },
  prediction: {
    chatView: 'Chat',
    systemPrompt: 'System Prompt',
    expectedAnswer: 'Expected Answer',
    extractedAnswer: 'Extracted Answer',
    copySuccess: 'Copied!',
    expandImage: 'Expand Image',
    generated: 'Generated Output',
    prediction: 'Prediction',
    pred: 'Extracted Answer',
    metadata: 'Metadata',
    toolCall: 'Tool Call',
    toolResult: 'Tool Result',
    copyContent: 'Copy',
    score: 'Score',
    input: 'Input',
    conversation: 'Conversation',
    evalResult: 'Evaluation Result',
    scoreJson: 'Score Detail',
    turnN: 'Turn ${n}',
    reasoning: 'Thinking',
    showReasoning: 'Show thinking',
    hideReasoning: 'Hide thinking',
    thresholdHint: 'Samples with normalized score ≥ threshold are counted as Pass.',
    searchByIndex: 'Go to index',
    searchByMsgId: 'Find msg id',
    indexNotFound: 'Index not found',
    msgIdNotFound: 'Message not found',
    copyMsgId: 'Copy id',
  },
  common: {
    loading: 'Loading...',
    noData: 'No data available',
    all: 'All',
    pass: 'Pass',
    fail: 'Fail',
    score: 'Score',
    page: 'Page',
    openNewTab: 'Open in New Tab',
    counts: 'Counts',
    input: 'Input',
    generated: 'Generated',
    gold: 'Gold',
    pred: 'Prediction',
    normalizedScore: 'Normalized Score',
    github: 'Star on GitHub',
    justNow: 'just now',
    secondsAgo: '${n}s ago',
    minutesAgo: '${n}m ago',
    hoursAgo: '${n}h ago',
    stop: 'Stop',
  },
  charts: {
    scoreAxisLabel: 'Score (%)',
    scoreHistogramAriaLabel: 'Score distribution histogram',
    groupedBarAriaLabel: 'Grouped bar chart',
    radarAriaLabel: 'Radar chart',
  },
  trace: {
    modelGenerate: 'Model Generate',
    toolCall: 'Tool Call',
    toolResult: 'Tool Result',
    envExec: 'Env Exec',
    error: 'Error',
    submit: 'Submit',
    step: 'Step',
    toolCallsCount: '${n} tool calls',
    stdout: 'stdout',
    arguments: 'Arguments',
    expandDetails: 'Show details',
    nudge: 'System Nudge',
    runStart: 'Run Start',
    runEnd: 'Run End',
    loopMessage: {
      max_steps_exceeded: 'Maximum steps exceeded',
      model_context_overflow: 'Model context window exceeded',
      no_tool_call_reminder: 'No tool was called — system reminder injected',
    },
  },
  reports: {
    title: 'Reports',
    pathLabel: 'Output Directory',
    scan: 'Scan',
    scanning: 'Scanning...',
    filters: {
      search: 'Search reports...',
      model: 'Model',
      dataset: 'Dataset',
      scoreRange: 'Score Range',
      sortBy: 'Sort By',
      time: 'Time',
      score: 'Score',
    },
    selectAll: 'Select All',
    selected: 'selected',
    compare: 'Compare',
    viewHtml: 'View HTML',
    samples: 'Samples',
    noReports: 'No reports found',
    scanFirst: 'Scan a directory to view reports',
  },
  reportDetail: {
    overview: 'Overview',
    details: 'Details',
    predictions: 'Predictions',
    viewHtml: 'View HTML Report',
    backToReports: 'Back to Reports',
    avgScore: 'Average Score',
    bestDataset: 'Best Dataset',
    worstDataset: 'Worst Dataset',
    totalSamples: 'Total Samples',
    overallScore: 'Overall Score',
    analysis: 'Analysis',
    subsetScores: 'Subset Scores',
    scoreDistribution: 'Score Distribution',
    metric: 'Metric',
    viewPredictions: 'View Predictions',
    taskConfig: 'Task Configuration',
    selectSubset: 'Select Subset',
    perfMetrics: 'Performance Metrics',
    avgLatency: 'Avg Latency',
    outputTps: 'Output TPS',
    reqPerSec: 'Req/s',
    samples: 'Requests',
    tokenUsage: 'Token Usage',
    latencyDist: 'Latency Distribution',
    p99Latency: 'P99 Latency',
    tokenInput: 'Input Tokens',
    tokenOutput: 'Output Tokens',
    tokenTotal: 'Total Tokens',
    stdDev: 'std dev',
    range: 'range',
    ttft: 'TTFT',
    tpot: 'TPOT',
    ttftDesc: 'Time to First Token',
    tpotDesc: 'Time per Output Token',
    timingMetrics: 'Latency & Timing',
    totalCount: 'Total',
    totalInputTokens: 'Total Input Tokens',
    totalOutputTokens: 'Total Output Tokens',
  },
  compare: {
    title: 'Compare Models',
    scoreComparison: 'Score Comparison',
    predictionComparison: 'Prediction Comparison',
    selectedModels: 'Selected Models',
    addModel: 'Add',
    average: 'Average',
    best: 'Best',
    commonDatasets: 'Common Datasets',
    allPass: 'All Pass',
    allFail: 'All Fail',
    showing: 'Showing',
    predictions: 'predictions',
    passRate: 'Pass Rate',
    needTwo: 'Select at least 2 reports to compare',
    noCommon: 'No common datasets found',
    dataset: 'Dataset',
    selectDataset: 'Select Dataset',
    selectSubset: 'Select Subset',
    scoreThreshold: 'Score Threshold',
    input: 'Input',
    goldAnswer: 'Gold Answer',
    generated: 'Generated',
    prediction: 'Prediction',
    score: 'Score',
    of: 'of',
    filterByModel: 'Filter',
    any: 'Any',
    maxThreeHint: 'Up to 3 models can be compared.',
    sample: 'Sample',
    maxThreeSelected: 'Only the first 3 will be compared.',
  },
  dashboard: {
    totalEvaluations: 'Total Evaluations',
    modelsEvaluated: 'Models Evaluated',
    datasetsUsed: 'Datasets Used',
    latestEval: 'Latest Evaluation',
    recentActivity: 'Recent Activity',
    viewAll: 'View All →',
    quickActions: 'Quick Actions',
    newEvaluation: 'New Evaluation',
    newEvalDesc: 'Run a new model evaluation task',
    newPerfTest: 'Performance Test',
    newPerfDesc: 'Benchmark inference throughput & latency',
    browseReports: 'Browse Reports',
    browseReportsDesc: 'Explore loaded evaluation results',
    scoreMatrix: 'Score Matrix',
    scoreMatrixDesc: 'Model × Dataset score heatmap',
    noReportsLoaded: 'No reports loaded',
    noReportsHint: 'Enter an output directory and click Scan to discover reports',
    noReportsYet: 'No reports found yet',
    model: 'Model',
    dataset: 'Dataset',
    score: 'Score',
    date: 'Date',
    neverText: '—',
    selectAll: 'Select all',
    deselectAll: 'Deselect all',
    loadAndView: 'Load & View',
    scanBtn: 'Scan',
    scanning: 'Scanning...',
    outputDir: 'Output Directory',
    pathPlaceholder: './outputs',
    viewBenchmarks: 'View Benchmarks',
    viewBenchmarksDesc: 'Browse the benchmark catalog',
    samples: 'samples',
    welcomeTitle: 'Welcome to EvalScope',
    welcomeDesc: 'Enter an output directory path and scan to get started',
    timelineView: 'Timeline',
    groupedView: 'By Model',
    byDatasetView: 'By Dataset',
    searchPlaceholder: 'Search models or datasets...',
    sortTime: 'Sort by Time',
    sortScore: 'Sort by Score',
    sortModel: 'Sort by Model',
    runs: 'runs',
    bestScore: 'best',
    evaluations: 'Evaluations',
    noEvals: 'No evaluations found',
  },
}

const zh: Dict = {
  nav: {
    dashboard: '看板',
    eval: '模型评估',
    perf: '性能测试',
    benchmarks: '基准测试',
    reports: '报告',
  },
  single: {
    selectReport: '选择报告',
    taskConfig: '任务配置',
    datasetsOverview: '数据集概览',
    datasetComponents: '数据集组成',
    datasetScores: '数据集分数',
    reportAnalysis: '报告智能分析',
    datasetScoresTable: '数据集分数表',
    datasetDetails: '数据集详情',
    selectDataset: '选择数据集',
    modelPrediction: '模型预测',
    selectSubset: '选择子集',
    answerMode: '答案模式',
    page: '页码',
    scoreThreshold: '分数阈值',
    summaryStats: '汇总统计',
    avgScore: '平均分',
    bestDataset: '最佳数据集',
    weakestDataset: '最弱数据集',
    totalSamples: '总样本数',
    radarChart: '得分雷达图',
    scoreDistribution: '得分分布',
    noScoreData: '暂无得分数据',
    samples: '样本',
  },
  multi: {
    selectReports: '请选择报告',
    modelsOverview: '模型概览',
    modelRadar: '模型对比雷达',
    modelScores: '模型对比分数',
    modelComparisonDetails: '模型对比详情',
    selectModelA: '选择模型A',
    selectModelB: '选择模型B',
    selectDataset: '选择数据集',
    modelPredictions: '模型预测',
    selectSubset: '选择子集',
    answerMode: '答案模式',
    scoreThreshold: '分数阈值',
    comparisonCounts: '对比统计',
    page: '页码',
    input: '输入',
    goldAnswer: '标准答案',
    score: '分数',
    normalizedScore: '归一化分数',
    prediction: '预测',
    generated: '生成结果',
    groupedBarChart: '数据集得分对比',
    noCommonDatasets: '所有模型中无公共数据集',
  },
  eval: {
    title: '模型评估',
    config: '评估配置',
    datasets: '数据集',
    limit: '限制数量',
    batchSize: '批大小',
    moreParams: '更多参数',
    repeats: '重复次数',
    timeout: '超时时间 (秒)',
    stream: '流式输出',
    temperature: 'Temperature',
    topP: 'Top P',
    maxTokens: 'Max Tokens',
    topK: 'Top K',
    datasetArgs: '数据集参数 (JSON)',
    startEval: '开始评估',
    status: '运行状态与日志',
    ready: '当前状态: 准备就绪',
    modelName: '模型名称',
    apiUrl: '模型API URL',
    apiKey: '模型API Key',
  },
  perf: {
    title: '性能测试',
    config: '性能测试配置',
    apiType: 'API类型',
    parallel: '并发数 (逗号分隔)',
    number: '总请求数 (逗号分隔)',
    rate: '速率限制 (请求/秒)',
    maxTokens: 'Max Tokens',
    minTokens: 'Min Tokens',
    dataset: '测试数据集',
    maxPromptLen: '最大Prompt长度',
    minPromptLen: '最小Prompt长度',
    startPerf: '开始性能测试',
    status: '运行状态与日志',
    ready: '当前状态: 准备就绪',
  },
  benchmarks: {
    title: '基准测试目录',
    all: '全部',
    text: '文本 (LLM)',
    multimodal: '多模态 (VLM)',
    noDescription: '暂无描述',
    search: '搜索基准测试...',
    use: '使用',
    useDescription: '使用此基准开始评测',
    totalCount: '${n} 个基准测试',
    filterByTag: '按标签筛选',
    subsets: '子集',
    samples: '样本数',
    shots: '${n}-shot',
    noResults: '未找到匹配的基准测试',
    clearFilters: '清除筛选',
    showing: '显示 ${n} / ${total}',
  },
  prediction: {
    chatView: '对话',
    systemPrompt: '系统提示词',
    expectedAnswer: '标准答案',
    extractedAnswer: '抽取答案',
    copySuccess: '已复制！',
    expandImage: '放大图片',
    generated: '生成结果',
    prediction: '预测结果',
    pred: '抽取答案',
    metadata: '元数据',
    toolCall: '工具调用',
    toolResult: '工具结果',
    copyContent: '复制',
    score: '得分',
    input: '输入',
    conversation: '对话历史',
    evalResult: '评估结果',
    scoreJson: '得分详情',
    turnN: '第 ${n} 轮',
    reasoning: '思考过程',
    showReasoning: '展开思考',
    hideReasoning: '收起思考',
    thresholdHint: '归一化分数 ≥ 阈值的样本视为 Pass。',
    searchByIndex: '跳转到索引',
    searchByMsgId: '查找消息 id',
    indexNotFound: '未找到该索引',
    msgIdNotFound: '未找到该消息',
    copyMsgId: '复制 id',
  },
  common: {
    loading: '加载中...',
    noData: '暂无数据',
    all: '全部',
    pass: '通过',
    fail: '失败',
    score: '分数',
    page: '页码',
    openNewTab: '在新标签页打开',
    counts: '统计',
    input: '输入',
    generated: '生成结果',
    gold: '标准答案',
    pred: '预测',
    normalizedScore: '归一化分数',
    github: 'GitHub 加星',
    justNow: '刚刚',
    secondsAgo: '${n}秒前',
    minutesAgo: '${n}分钟前',
    hoursAgo: '${n}小时前',
    stop: '停止',
  },
  charts: {
    scoreAxisLabel: '得分 (%)',
    scoreHistogramAriaLabel: '得分分布直方图',
    groupedBarAriaLabel: '分组柱状图',
    radarAriaLabel: '雷达图',
  },
  trace: {
    modelGenerate: '模型生成',
    toolCall: '工具调用',
    toolResult: '工具结果',
    envExec: '环境执行',
    error: '错误',
    submit: '提交',
    step: '步骤',
    toolCallsCount: '${n} 个工具调用',
    stdout: '输出',
    arguments: '参数',
    expandDetails: '展开详情',
    nudge: '系统提醒',
    runStart: '运行开始',
    runEnd: '运行结束',
    loopMessage: {
      max_steps_exceeded: '达到最大步数上限',
      model_context_overflow: '超出模型上下文窗口',
      no_tool_call_reminder: '未调用工具——系统已注入提醒',
    },
  },
  reports: {
    title: '报告',
    pathLabel: '输出目录',
    scan: '扫描',
    scanning: '扫描中...',
    filters: {
      search: '搜索报告...',
      model: '模型',
      dataset: '数据集',
      scoreRange: '分数范围',
      sortBy: '排序',
      time: '时间',
      score: '分数',
    },
    selectAll: '全选',
    selected: '已选',
    compare: '对比',
    viewHtml: '查看HTML',
    samples: '样本数',
    noReports: '未找到报告',
    scanFirst: '扫描目录以查看报告',
  },
  reportDetail: {
    overview: '概览',
    details: '详情',
    predictions: '预测浏览',
    viewHtml: '查看HTML报告',
    backToReports: '返回报告列表',
    avgScore: '平均分数',
    bestDataset: '最佳数据集',
    worstDataset: '最差数据集',
    totalSamples: '总样本数',
    overallScore: '总体得分',
    analysis: '分析',
    subsetScores: '子集分数',
    scoreDistribution: '得分分布',
    metric: '指标',
    viewPredictions: '查看预测',
    taskConfig: '任务配置',
    selectSubset: '选择子集',
    perfMetrics: '性能指标',
    avgLatency: '平均延迟',
    outputTps: '输出TPS',
    reqPerSec: '请求/秒',
    samples: '请求数',
    tokenUsage: 'Token用量',
    latencyDist: '延迟分布',
    p99Latency: 'P99延迟',
    tokenInput: '输入 Token',
    tokenOutput: '输出 Token',
    tokenTotal: '总 Token',
    stdDev: '标准差',
    range: '范围',
    ttft: 'TTFT',
    tpot: 'TPOT',
    ttftDesc: '首 Token 时间',
    tpotDesc: '每 Token 时间',
    timingMetrics: '延迟与时序指标',
    totalCount: '总计',
    totalInputTokens: '输入 Token 总量',
    totalOutputTokens: '输出 Token 总量',
  },
  compare: {
    title: '模型对比',
    scoreComparison: '分数对比',
    predictionComparison: '预测对比',
    selectedModels: '已选模型',
    addModel: '添加',
    average: '平均',
    best: '最佳',
    commonDatasets: '共同数据集',
    allPass: '全部通过',
    allFail: '全部失败',
    showing: '显示',
    predictions: '条预测',
    passRate: '通过率',
    needTwo: '请选择至少2个报告进行对比',
    noCommon: '未找到共同数据集',
    dataset: '数据集',
    selectDataset: '选择数据集',
    selectSubset: '选择子集',
    scoreThreshold: '分数阈值',
    input: '输入',
    goldAnswer: '标准答案',
    generated: '生成结果',
    prediction: '预测结果',
    score: '分数',
    of: '/',
    filterByModel: '筛选',
    any: '不限',
    maxThreeHint: '最多支持对比 3 个模型。',
    sample: '样本',
    maxThreeSelected: '仅对比前 3 个。',
  },
  dashboard: {
    totalEvaluations: '评测总数',
    modelsEvaluated: '已评估模型',
    datasetsUsed: '使用数据集',
    latestEval: '最近评测',
    recentActivity: '最近活动',
    viewAll: '查看全部 →',
    quickActions: '快速操作',
    newEvaluation: '新建评估',
    newEvalDesc: '运行新的模型评估任务',
    newPerfTest: '性能测试',
    newPerfDesc: '测试推理吞吐量与延迟',
    browseReports: '浏览报告',
    browseReportsDesc: '探索已加载的评测结果',
    scoreMatrix: '得分矩阵',
    scoreMatrixDesc: '模型 × 数据集得分热力图',
    noReportsLoaded: '尚未加载报告',
    noReportsHint: '输入输出目录路径并点击扫描来发现报告',
    noReportsYet: '暂未发现报告',
    model: '模型',
    dataset: '数据集',
    score: '分数',
    date: '日期',
    neverText: '—',
    selectAll: '全选',
    deselectAll: '取消全选',
    loadAndView: '加载并查看',
    scanBtn: '扫描',
    scanning: '扫描中...',
    outputDir: '输出目录',
    pathPlaceholder: './outputs',
    viewBenchmarks: '查看基准测试',
    viewBenchmarksDesc: '浏览基准测试目录',
    samples: '样本',
    welcomeTitle: '欢迎使用 EvalScope',
    welcomeDesc: '输入输出目录路径并扫描即可开始',
    timelineView: '时间线',
    groupedView: '按模型',
    byDatasetView: '按数据集',
    searchPlaceholder: '搜索模型或数据集...',
    sortTime: '按时间排序',
    sortScore: '按分数排序',
    sortModel: '按模型排序',
    runs: '次评估',
    bestScore: '最高',
    evaluations: '评估列表',
    noEvals: '暂无评估记录',
  },
}

const translations: Record<Locale, Dict> = { en, zh }

export function lookupTranslation(locale: Locale, path: string): string {
  const keys = path.split('.')
  let node: string | Dict = translations[locale]
  for (const key of keys) {
    if (typeof node === 'string') return path
    node = (node as Dict)[key]
    if (node === undefined) return path
  }
  return typeof node === 'string' ? node : path
}
