<script setup>
import { ref, onMounted, watch, nextTick } from 'vue'
import { useLeaderboardData } from '@/composables/useLeaderboardData.js'
import Chart from '@/components/Chart.vue'
import { computed } from 'vue'
import { parsedHeaderHtml } from '@/utils/mk2html.js'

// 使用数据管理 composable
const {
  leaderboard,
  csvHeaders,
  loading,
  error,
  selectedMode,
  visibleColumns,
  selectableColumns,
  dataGroups,
  selectedDataName,
  modelSeriesICAvg,
  selectedDataNameChart,
  autoShowSeries,
  headerDisplayMap,
  dataNameDisplayMap,
  modelTypeGroups,
  selectedModelType,
  filteredLeaderboard,
  displayedColumns,
  fetchAndLoadCsv,
  selectAll,
  clearAll,
  selectAllModelTypes,
  clearAllModelTypes,
  formatCell,
  // 排序 API
  sortKey,
  sortDesc,
  setSortKey,
  init
} = useLeaderboardData()

const isSeries = computed(() => selectedMode.value === 'ModelSeries')

// theme (dark mode) support: sync with document root class and localStorage
const isDark = ref(false)

// 图表区域ref
const chartSection = ref(null)

// 记录上一次选择的图表数据集，用于区分初始加载和用户点击
const lastSelectedDataNameChart = ref('')

// header markdown 内容
const headerMarkdown = ref(`

**Information Capacity** evaluates an LLM's **efficiency** based on text compression performance relative to computational complexity, harnessing the inherent correlation between **compression** and **intelligence**. 
Larger models can predict the next token more accurately, leading to higher compression gains but at increased computational costs. 
Consequently, a series of models with varying sizes exhibits **consistent** information capacity, which can be used to compare model capability across model series and predict model performance within a series.
It also facilitates dynamic routing of different-sized models for efficient handling of tasks with varying difficulties, which is especially relevant to the device-edge-cloud infrastructure detailed in the **AI Flow** framework.
With the rapid evolution of edge intelligence, we believe that this hierarchical network will replace the mainstream cloud-centric computing scheme in the near future.


If you want to add your evaluation results to the leaderboard, please submit a discussion at [this huggingface space](https://huggingface.co/spaces/TeleAI-AI-Flow/InformationCapacityLeaderboard/discussions/new).

`)

const title = 'Information Capacity Leaderboard'

const lastUpdatedTime = '3/10/2026 10:55'

const headerInfo = parsedHeaderHtml(headerMarkdown.value)


// 当图表数据集变化时，滚动到图表区域底部（仅当用户点击时）
watch(selectedDataNameChart, (newVal) => {
  if (lastSelectedDataNameChart.value && lastSelectedDataNameChart.value !== newVal) {
    nextTick(() => {
      chartSection.value?.scrollIntoView({ behavior: 'smooth', block: 'end' })
    })
  }
  lastSelectedDataNameChart.value = newVal
})

onMounted(() => {
  init()
})

onMounted(() => {
  const stored = localStorage.getItem('theme')
  if (stored === 'dark') {
    isDark.value = true
  } else if (stored === 'light') {
    isDark.value = false
  } else {
    // follow system preference when no stored preference
    isDark.value = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
  }
})

watch(isDark, (val) => {
  try {
    if (val) document.documentElement.classList.add('dark')
    else document.documentElement.classList.remove('dark')
    localStorage.setItem('theme', val ? 'dark' : 'light')
  } catch (e) {
    // ignore if SSR or unavailable
  }
})

function clearModelTypeSelection() {
  selectAllModelTypes()
}
</script>

<template>
  <div
    class="min-h-screen bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:via-gray-800 dark:to-gray-800 py-12 px-4 sm:px-6 lg:px-8">
    <div class=" mx-auto">
      <header class="mb-4 flex items-start justify-between mr-4">
        <div>
          <h1 class="text-3xl font-extrabold text-gray-900 dark:text-gray-100">{{ title }}</h1>
          <!-- <p class="mt-1 text-sm text-gray-600 dark:text-gray-300">LLM IC Leaderboard Demo</p> -->
          <div v-html="headerInfo" class="py-7"></div>
        </div>
        <div class="flex items-center">
          <!-- 固定正方形容器，内部图片保持纵横比且居中 -->
          <div class="h-40 w-40 flex items-center justify-center  rounded-md overflow-hidden p-2">
            <img src="/logo.png" alt="Logo" class="max-h-full max-w-full object-contain" />
          </div>
        </div>
      </header>


      <div class="bg-white dark:bg-gray-900/60 shadow rounded-lg overflow-hidden">
        <div
          class="px-6 py-4 border-b bg-gradient-to-r from-indigo-50 via-white to-white dark:bg-gradient-to-r dark:from-gray-800 dark:via-gray-900 dark:to-gray-900">
          <div class="flex items-center justify-between">
            <h2 class="text-lg font-medium text-gray-800 dark:text-gray-50">Leaderboard</h2>
            <div class="text-sm text-gray-500 dark:text-gray-300">Last updated on {{ lastUpdatedTime }}</div>
          </div>
        </div>
        <!-- 筛选（模型分类，模型系列分类） -->
        <div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800">
          <div class="flex items-center gap-3">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-200">Shown as</span>
            <div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto">
              <!-- <label class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer" :class="{'bg-gray-100 dark:bg-gray-700': selectedDataName==='all'}">
                <input type="radio" class="hidden" value="all" v-model="selectedDataName" /> 全部
              </label> -->
              <label @click="selectedMode = 'Model'"
                class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300"
                :class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedMode === 'Model' }">
                Individual Models
              </label>
              <label @click="selectedMode = 'ModelSeries'"
                class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300"
                :class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedMode === 'ModelSeries' }">
                Model Series
              </label>
            </div>
            <div v-else class="text-sm text-gray-500 dark:text-gray-400">（数据集中未检测到 data_name 列）</div>
          </div>
        </div>

        <!-- 数据集筛选区域（独立于列筛选） -->
        <div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800">
          <div class="flex items-center gap-3">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-200">Dataset</span>
            <div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto">
              <!-- <label class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer" :class="{'bg-gray-100 dark:bg-gray-700': selectedDataName==='all'}">
                <input type="radio" class="hidden" value="all" v-model="selectedDataName" /> 全部
              </label> -->
              <label v-for="g in dataGroups" :key="g"
                class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300"
                :class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedDataName === g }">
                <input type="radio" class="hidden" :value="g" v-model="selectedDataName" /> <span
                  class="whitespace-nowrap">{{ dataNameDisplayMap[g] ?
                    dataNameDisplayMap[g] : g }}</span>
              </label>
            </div>
            <div v-else class="text-sm text-gray-500 dark:text-gray-400">（数据集中未检测到 data_name 列）</div>
          </div>
        </div>


        <!-- 模型类型筛选区域 -->
        <div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800">
          <div class="flex items-center gap-3">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-200 whitespace-nowrap">Model Series</span>
            <div class="flex items-center gap-2">
              <button @click="clearModelTypeSelection"
                class="whitespace-nowrap text-sm px-2 py-1 bg-white/90 dark:bg-gray-700/60 border border-gray-200 dark:border-gray-600 rounded text-gray-700 dark:text-gray-200 hover:bg-white dark:hover:bg-gray-600 transition">
                全选
              </button>
              <button @click="clearAllModelTypes"
                class="whitespace-nowrap text-sm px-2 py-1 bg-transparent border border-gray-200 dark:border-gray-700 rounded text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition">
                清除
              </button>
            </div>
            <div v-if="modelTypeGroups.length > 0" class="flex flex-wrap gap-2 items-center">
              <label v-for="g in modelTypeGroups" :key="g"
                class="flex items-center gap-2 text-sm bg-white dark:bg-gray-800 px-3 py-1 rounded-full border border-gray-200 dark:border-gray-700 hover:shadow-sm whitespace-nowrap">
                <input type="checkbox" :value="g" v-model="selectedModelType"
                  class="h-4 w-4 text-indigo-600 dark:text-indigo-400 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded" />
                <span class="truncate text-gray-800 dark:text-gray-50">{{ g }}</span>
              </label>
            </div>
            <div v-else class="text-sm text-gray-500 dark:text-gray-400">（未配置模型类型映射）</div>
          </div>
        </div>

        <!-- 内联列选择区域：pills 风格，支持水平滚动，并兼容深色/浅色模式 -->
        <div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800" v-show="!isSeries">
          <div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
            <div class="flex items-center gap-3">
              <span class="text-sm font-medium text-gray-700 dark:text-gray-200">Visible Columns</span>
              <div class="flex items-center gap-2">
                <button @click.prevent="selectAll"
                  class="text-sm px-2 py-1 bg-white/90 dark:bg-gray-700/60 border border-gray-200 dark:border-gray-600 rounded text-gray-700 dark:text-gray-200 hover:bg-white dark:hover:bg-gray-600 transition">全选</button>
                <button @click.prevent="clearAll"
                  class="text-sm px-2 py-1 bg-transparent border border-gray-200 dark:border-gray-700 rounded text-gray-600 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 transition">清除</button>
              </div>
            </div>

            <div class="flex-1 overflow-x-auto">
              <div class="flex gap-2 items-center px-1 py-2">
                <label v-for="h in selectableColumns" :key="h"
                  class="flex items-center gap-2 text-sm bg-white dark:bg-gray-800 px-3 py-1 rounded-full border border-gray-200 dark:border-gray-700 hover:shadow-sm whitespace-nowrap">
                  <input type="checkbox" :value="h" v-model="visibleColumns"
                    class="h-4 w-4 text-indigo-600 dark:text-indigo-400 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded" />
                  <span class="truncate text-gray-800 dark:text-gray-50">{{ headerDisplayMap[h] || h }}</span>
                </label>
              </div>
            </div>
          </div>
        </div>

        <div class="p-4 overflow-x-auto">
          <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
            <thead class="bg-gray-50 dark:bg-gradient-to-r dark:from-gray-800 dark:to-gray-900">
              <tr>
                <!-- 序号列 -->
                <!-- <th class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">RANK</th> -->
                <!-- ModelSeries 模式下使用计算结果列，否则使用普通列 -->
                <template v-if="selectedMode === 'ModelSeries'">
                  <th v-if="visibleColumns.includes('rank')"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap['rank'] || 'rank' }}</span>
                    </div>
                  </th>
                  <th v-if="visibleColumns.includes('model_series')"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap['model_series'] || 'ModelSeries' }}</span>
                    </div>
                  </th>
                  <th v-if="visibleColumns.includes('constant')"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap['constant']}}</span>
                    </div>
                  </th>
                  <th v-if="visibleColumns.includes('ic')" @click="setSortKey('ic')"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap['ic']}} (AVG)</span>
                      <span v-if="sortKey === 'ic'" class="text-xs text-gray-600 dark:text-gray-300">
                        <span v-if="sortDesc">▼</span>
                        <span v-else>▲</span>
                      </span>
                    </div>
                  </th>
                   <th v-if="visibleColumns.includes('model_source')" @click="setSortKey('model_source')"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap['model_source']}} </span>
                      <span v-if="sortKey === 'model_source'" class="text-xs text-gray-600 dark:text-gray-300">
                        <span v-if="sortDesc">▼</span>
                        <span v-else>▲</span>
                      </span>
                    </div>
                  </th>
                </template>
                <template v-else>
                  <th v-for="h in displayedColumns" :key="h" @click="setSortKey(h)"
                    class="px-4 py-2 text-left text-xs font-medium text-gray-500 dark:text-gray-300 tracking-wider cursor-pointer select-none">
                    <div class="flex items-center gap-2">
                      <span class="whitespace-nowrap">{{ headerDisplayMap[h] || h }}</span>
                      <span v-if="sortKey === h" class="text-xs text-gray-600 dark:text-gray-300">
                        <span v-if="sortDesc">▼</span>
                        <span v-else>▲</span>
                      </span>
                    </div>
                  </th>
                </template>
              </tr>
            </thead>
            <tbody class="bg-white dark:bg-transparent divide-y divide-gray-100 dark:divide-gray-700">
              <!-- ModelSeries mode -> 显示 modelSeriesICAvg -->
              <template v-if="selectedMode === 'ModelSeries'">
                <tr v-for="(row, idx) in modelSeriesICAvg" :key="row.ModelSeries"
                  class="hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150">
                  <td class="px-4 py-3 whitespace-nowrap font-medium text-gray-800 dark:text-gray-50">{{ idx + 1 }}</td>
                  <td v-if="visibleColumns.includes('model_series')" class="px-4 py-3 whitespace-nowrap">
                    <div class="text-sm text-gray-800 dark:text-gray-50">{{ row.ModelSeries }}</div>
                  </td>
                  
                  <td v-if="visibleColumns.includes('constant')"
                    class="px-4 py-3 whitespace-nowrap">
                    <div class="text-sm text-gray-800 dark:text-gray-50">{{ row.Constant }}</div>
                  </td>

                  <td v-if="visibleColumns.includes('ic')"
                    class="px-4 py-3 whitespace-nowrap">
                    <div class="text-sm text-gray-800 dark:text-gray-50">{{ row.IC }}</div>
                  </td>

                  <td v-if="visibleColumns.includes('model_source')"
                    class="px-4 py-3 whitespace-nowrap">
                    <div class="text-sm text-gray-800 dark:text-gray-50">{{ row.ModelSource }}</div>
                  </td>
                </tr>
              </template>

              <!-- 默认 Model 模式 -> 现有表格 -->
              <template v-else>
                <tr v-for="(model, index) in filteredLeaderboard" :key="model.rank" :class="{
                  // 'bg-yellow-50 dark:bg-yellow-700/25': index === 0,
                  // 'bg-gray-50 dark:bg-gray-800/60': index === 1,
                  // 'bg-indigo-50 dark:bg-indigo-700/25': index === 2
                }" class="hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150">
                  <td v-for="h in displayedColumns" :key="h" class="px-4 py-3 whitespace-nowrap">
                    <div class="text-sm text-gray-800 dark:text-gray-50">{{ formatCell(h, model) }}</div>
                  </td>
                </tr>
              </template>
            </tbody>
          </table>
        </div>
      </div>

      <!-- 图表区域 -->
      <div ref="chartSection" class="mt-8 bg-white dark:bg-gray-900/60 shadow rounded-lg overflow-hidden">
        <!-- 图表头部 -->
        <div
          class="px-6 py-4 border-b bg-gradient-to-r from-indigo-50 via-white to-white dark:bg-gradient-to-r dark:from-gray-800 dark:via-gray-900 dark:to-gray-900">
          <h2 class="text-lg font-medium text-gray-800 dark:text-gray-50">Data visualization</h2>
        </div>

        <!-- 图表数据集筛选区域 -->
        <div class="px-6 py-3 border-b bg-gray-50 dark:bg-gradient-to-b dark:from-gray-900 dark:to-gray-800">
          <div class="flex items-center gap-3">
            <span class="text-sm font-medium text-gray-700 dark:text-gray-200">Dataset</span>
            <div v-if="dataGroups.length > 0" class="flex gap-2 items-center overflow-x-auto">
              <label v-for="g in dataGroups" :key="g"
                class="px-2 py-1 rounded-full border border-gray-200 dark:border-gray-700 text-sm cursor-pointer dark:text-slate-300"
                :class="{ 'bg-gray-100 dark:bg-gray-700 dark:text-white': selectedDataNameChart === g }">
                <input type="radio" class="hidden" :value="g" v-model="selectedDataNameChart" /> <span
                  class="whitespace-nowrap">{{ dataNameDisplayMap[g]
                    ? dataNameDisplayMap[g] : g }}</span>
              </label>
            </div>
            <div v-else class="text-sm text-gray-500 dark:text-gray-400">（数据集中未检测到 data_name 列）</div>
          </div>
        </div>

        <!-- 图表内容 -->
        <div class="p-6">
          <Chart :autoShowSeries="autoShowSeries" />
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped></style>