import React, { useEffect, useState } from 'react'
import { ArrowDownTrayIcon } from '@heroicons/react/24/solid'
import QualityMetricsTable from './QualityMetricsTable'

interface LeaderboardTableProps {
  benchmarkData: any
  selectedModels: Set<string>
}

interface Row {
  metric: string
  [key: string]: string | number
}

interface Groups {
  [group: string]: { [subgroup: string]: string[] }
}

interface SortState {
  [overallMetric: string]: {
    [model: string]: { direction: 'asc' | 'desc' }
  }
}

const OVERALL_ROW = 'Overall'
const DEFAULT_SELECTED_METRICS = new Set(['log10_p_value'])

const OverallMetricFilter: React.FC<{
  overallMetrics: string[]
  selectedOverallMetrics: Set<string>
  setSelectedOverallMetrics: (metrics: Set<string>) => void
}> = ({ overallMetrics, selectedOverallMetrics, setSelectedOverallMetrics }) => {
  const toggleMetric = (metric: string) => {
    const newSelected = new Set(selectedOverallMetrics)
    if (newSelected.has(metric)) {
      newSelected.delete(metric)
    } else {
      newSelected.add(metric)
    }
    setSelectedOverallMetrics(newSelected)
  }
  return (
    <div className="w-full">
      <fieldset className="fieldset w-full p-4 rounded border border-gray-700 bg-base-200">
        <legend className="fieldset-legend font-semibold">
          Metrics ({selectedOverallMetrics.size}/{overallMetrics.length})
        </legend>
        <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-1 max-h-48 overflow-y-auto pr-2">
          {overallMetrics.map((metric) => (
            <label key={metric} className="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                className="form-checkbox h-4 w-4"
                checked={selectedOverallMetrics.has(metric)}
                onChange={() => toggleMetric(metric)}
              />
              <span className="truncate" title={metric}>
                {metric}
              </span>
            </label>
          ))}
        </div>
      </fieldset>
    </div>
  )
}

const LeaderboardTable: React.FC<LeaderboardTableProps> = ({ benchmarkData, selectedModels }) => {
  const [tableRows, setTableRows] = useState<Row[]>([])
  const [tableHeader, setTableHeader] = useState<string[]>([])
  const [error, setError] = useState<string | null>(null)
  const [groupRows, setGroupRows] = useState<Groups>({})
  const [openGroupRows, setOpenGroupRows] = useState<{ [key: string]: boolean }>({})
  const [openSubGroupRows, setOpenSubGroupRows] = useState<{
    [key: string]: { [key: string]: boolean }
  }>({})
  const [selectedMetrics, setSelectedMetrics] = useState<Set<string>>(new Set())
  const [overallMetrics, setOverallMetrics] = useState<string[]>([])
  const [selectedOverallMetrics, setSelectedOverallMetrics] = useState<Set<string>>(new Set())
  const [sortState, setSortState] = useState<SortState>({})

  // Add state for row-based column sorting
  const [selectedRowForSort, setSelectedRowForSort] = useState<{
    [rowKey: string]: { direction: 'asc' | 'desc' }
  }>({})

  const models = tableHeader.filter((model) => selectedModels.has(model))

  useEffect(() => {
    if (!benchmarkData) {
      return
    }
    try {
      const data = benchmarkData
      const rows: Row[] = data['rows']
      const allGroups = data['groups'] as { [key: string]: string[] }
      const { Overall: overallGroup, ...groups } = allGroups
      const uniqueMetrics = new Set<string>()
      overallGroup?.forEach((metric) => {
        if (metric.includes('_')) {
          const metricName = metric.split('_').slice(1).join('_')
          uniqueMetrics.add(metricName)
        }
      })
      setOverallMetrics(Array.from(uniqueMetrics).sort())
      setSelectedOverallMetrics(new Set(DEFAULT_SELECTED_METRICS))
      // setSelectedOverallMetrics(new Set(Array.from(uniqueMetrics)))
      const groupsData = Object.entries(allGroups)
        .sort(([groupA], [groupB]) => {
          if (groupA === OVERALL_ROW) return -1
          if (groupB === OVERALL_ROW) return 1
          return groupA.localeCompare(groupB)
        })
        .reduce(
          (acc, [group, metrics]) => {
            const sortedMetrics = [...metrics].sort()
            acc[group] = sortedMetrics.reduce<{ [key: string]: string[] }>((subAcc, metric) => {
              const [mainGroup, subGroup] = metric.split('_')
              if (!subAcc[mainGroup]) {
                subAcc[mainGroup] = []
              }
              subAcc[mainGroup].push(metric)
              return subAcc
            }, {})
            acc[group] = Object.fromEntries(
              Object.entries(acc[group]).sort(([subGroupA], [subGroupB]) =>
                subGroupA.localeCompare(subGroupB)
              )
            )
            return acc
          },
          {} as { [key: string]: { [key: string]: string[] } }
        )
      const allKeys: string[] = Array.from(new Set(rows.flatMap((row) => Object.keys(row))))
      const headers = allKeys.filter((key) => key !== 'metric')
      const initialOpenGroups: { [key: string]: boolean } = {}
      const initialOpenSubGroups: { [key: string]: { [key: string]: boolean } } = {}
      Object.keys(groupsData).forEach((group) => {
        initialOpenGroups[group] = false
        initialOpenSubGroups[group] = {}
        Object.keys(groupsData[group]).forEach((subGroup) => {
          initialOpenSubGroups[group][subGroup] = false
        })
      })
      const allMetrics = Object.values(allGroups).flat()
      setSelectedMetrics(new Set(allMetrics))
      setTableHeader(headers)
      setTableRows(rows)
      setGroupRows(groupsData)
      setOpenGroupRows(initialOpenGroups)
      setOpenSubGroupRows(initialOpenSubGroups)
      setSelectedRowForSort({
        [getColumnSortRowKey(OVERALL_ROW, null, null)]: { direction: 'asc' },
      })
      setError(null)
    } catch (err: any) {
      setError('Failed to parse benchmark data, please try again: ' + err.message)
    }
  }, [benchmarkData])

  const handleRowSort = (overallMetric: string, model: string) => {
    setSortState((prev) => {
      const prevDir = prev[overallMetric]?.[model]?.direction
      let newSortState: SortState = {}
      if (!prevDir) {
        // No sort yet, set to 'asc'
        newSortState[overallMetric] = { [model]: { direction: 'asc' } }
      } else if (prevDir === 'asc') {
        // Was 'asc', set to 'desc'
        newSortState[overallMetric] = { [model]: { direction: 'desc' } }
      }
      // Else revert back to unsorted state
      return newSortState
    })
  }

  // Helper to generate a stable composite key for row-based column sorting
  function getColumnSortRowKey(
    group: string | null,
    subGroup: string | null,
    metric: string | null
  ) {
    return `${group ?? ''}||${subGroup ?? ''}||${metric ?? ''}`
  }

  // Update handleColumnSort to use setSelectedRowForSort
  const handleColumnSort = (
    group: string | null,
    subGroup: string | null,
    metric: string | null
  ) => {
    const rowKey = getColumnSortRowKey(group, subGroup, metric)
    setSelectedRowForSort((prev) => {
      const prevDir = prev[rowKey]?.direction
      const newSortState: { [rowKey: string]: { direction: 'asc' | 'desc' } } = {}
      if (!prevDir) {
        newSortState[rowKey] = { direction: 'asc' }
      } else if (prevDir === 'asc') {
        newSortState[rowKey] = { direction: 'desc' }
      } else if (prevDir === 'desc') {
        delete newSortState[rowKey]
      }
      return newSortState
    })
  }

  // Helper to get current row sort config for a row
  function getColumnSort(group: string | null, subGroup: string | null, metric: string | null) {
    return selectedRowForSort[getColumnSortRowKey(group, subGroup, metric)] || null
  }

  const getSortConfig = () => {
    // Find the first sorted column (overallMetric, model)
    for (const overallMetric of overallMetrics) {
      if (!selectedOverallMetrics.has(overallMetric)) continue
      for (const model of models) {
        if (sortState[overallMetric]?.[model]) {
          return { overallMetric, model, direction: sortState[overallMetric][model].direction }
        }
      }
    }
    return null
  }

  // Find all metrics matching a particular extracted metric name (like "log10_p_value")
  const findAllMetricsForName = (metricName: string): string[] => {
    return tableRows
      .filter((row) => {
        const metric = row.metric as string
        if (metric.includes('_')) {
          const extractedName = metric.split('_').slice(1).join('_')
          return extractedName.endsWith(metricName)
        }
        return false
      })
      .map((row) => row.metric as string)
  }

  // Identify metrics that don't belong to any overall metric group
  const findQualityMetrics = (): string[] => {
    // Get all metrics from the table rows
    const allMetrics = tableRows.map((row) => row.metric as string)

    // Filter to only include metrics that aren't part of any of the overall metrics
    return allMetrics.filter((metric) => {
      // Check if this metric is part of any of the overall metrics
      for (const overall of overallMetrics) {
        if (metric.endsWith(`_${overall}`) || metric === overall) {
          return false // This metric belongs to an overall group
        }
      }
      return true
    })
  }

  // Calculate average and standard deviation for a set of metrics for a specific column
  const calculateStats = (
    metricNames: string[],
    columnKey: string
  ): { avg: number; stdDev: number } => {
    const values = metricNames
      .map((metricName) => {
        const row = tableRows.find((row) => row.metric === metricName)
        return row ? Number(row[columnKey]) : NaN
      })
      .filter((value) => !isNaN(value))

    if (values.length === 0) return { avg: NaN, stdDev: NaN }

    const avg = values.reduce((sum, val) => sum + val, 0) / values.length

    const squareDiffs = values.map((value) => {
      const diff = value - avg
      return diff * diff
    })
    const variance = squareDiffs.reduce((sum, sqrDiff) => sum + sqrDiff, 0) / values.length
    const stdDev = Math.sqrt(variance)

    return { avg, stdDev }
  }

  // Filter metrics by group and/or subgroup
  const filterMetricsByGroupAndSubgroup = (
    metricNames: string[],
    group: string | null = null,
    subgroup: string | null = null
  ): string[] => {
    // If no group specified, return all metrics
    if (!group) return metricNames

    // Get all metrics for the specified group
    const groupMetrics = Object.values(groupRows[group] || {}).flat() as string[]

    // If subgroup is specified, further filter to that subgroup
    if (subgroup && groupRows[group]?.[subgroup]) {
      return metricNames.filter(
        (metric) => groupRows[group][subgroup].includes(metric) && selectedMetrics.has(metric)
      )
    }

    // Otherwise return all metrics in the group
    return metricNames.filter(
      (metric) => groupMetrics.includes(metric) && selectedMetrics.has(metric)
    )
  }

  // Before rendering group rows:
  const groupSortConfig = getSortConfig()
  let groupEntries = Object.entries(groupRows)
  //.filter(([group]) => group !== OVERALL_ROW) // Keep overall row for now
  if (groupSortConfig) {
    groupEntries = groupEntries.sort(([groupA, subGroupsA], [groupB, subGroupsB]) => {
      // For each group, get all metrics in the group for the selected overallMetric
      const allMetricsWithName = findAllMetricsForName(groupSortConfig.overallMetric)
      const getGroupAvg = (subGroups: { [key: string]: string[] }) => {
        const allGroupMetrics = Object.values(subGroups).flat()
        const metricsInGroupForThisMetric = allGroupMetrics.filter((m) =>
          allMetricsWithName.includes(m)
        )
        const stats = calculateStats(metricsInGroupForThisMetric, groupSortConfig.model)
        return stats.avg
      }
      const avgA = getGroupAvg(subGroupsA)
      const avgB = getGroupAvg(subGroupsB)
      if (isNaN(avgA) && isNaN(avgB)) return 0
      if (isNaN(avgA)) return 1
      if (isNaN(avgB)) return -1
      return groupSortConfig.direction === 'asc' ? avgA - avgB : avgB - avgA
    })
  }

  // Compute model order for each overall metric before rendering
  const modelOrderByOverallMetric: { [metric: string]: string[] } = {}
  overallMetrics
    .filter((metric) => selectedOverallMetrics.has(metric))
    .forEach((metric) => {
      // Check if there is an active row-based column sort for this metric
      let sortedModels: string[] | null = null
      // Find the active rowKey for this metric in rowColumnSort
      const activeRowKey = Object.keys(selectedRowForSort).find((rowKey) => {
        // rowKey format: group||subGroup||metric
        const [group, subGroup, rowMetric] = rowKey.split('||')
        // If rowMetric is empty, it's a group or subgroup row
        if (rowMetric === '' && metric === metric) return true
        // If rowMetric matches this metric, it's an individual metric row
        if (rowMetric && findAllMetricsForName(metric).includes(rowMetric)) return true
        return false
      })
      if (activeRowKey && selectedRowForSort[activeRowKey]) {
        const direction = selectedRowForSort[activeRowKey].direction
        const [group, subGroup, rowMetric] = activeRowKey.split('||')
        if (!rowMetric) {
          // Group or subgroup row: sort by average for this group/subgroup and metric
          // Find all metrics in this group/subgroup for this overall metric
          let relevantMetrics: string[] = []
          if (group && !subGroup) {
            // Group row
            const groupMetrics = Object.values(groupRows[group] || {}).flat() as string[]
            relevantMetrics = groupMetrics.filter((m: string) =>
              findAllMetricsForName(metric).includes(m)
            )
          } else if (group && subGroup) {
            // Subgroup row
            relevantMetrics = (groupRows[group]?.[subGroup] || []).filter((m: string) =>
              findAllMetricsForName(metric).includes(m)
            )
          }
          sortedModels = [...models].sort((a, b) => {
            const statsA = calculateStats(relevantMetrics, a)
            const statsB = calculateStats(relevantMetrics, b)
            if (isNaN(statsA.avg) && isNaN(statsB.avg)) return 0
            if (isNaN(statsA.avg)) return 1
            if (isNaN(statsB.avg)) return -1
            return direction === 'asc' ? statsA.avg - statsB.avg : statsB.avg - statsA.avg
          })
        } else {
          // Individual metric row: sort by value for that metric
          sortedModels = [...models].sort((a, b) => {
            const rowA = tableRows.find((r) => r.metric === rowMetric)
            const rowB = rowA // same row
            const valA = rowA ? Number(rowA[a]) : NaN
            const valB = rowB ? Number(rowB[b]) : NaN
            if (isNaN(valA) && isNaN(valB)) return 0
            if (isNaN(valA)) return 1
            if (isNaN(valB)) return -1
            return direction === 'asc' ? valA - valB : valB - valA
          })
        }
      }
      modelOrderByOverallMetric[metric] =
        sortedModels || tableHeader.filter((model) => selectedModels.has(model))
    })

  const visibleMetrics = overallMetrics.filter((metric) => selectedOverallMetrics.has(metric))

  return (
    <div className="rounded">
      {error && <div className="text-red-500">{error}</div>}
      {!error && (
        <div className="flex flex-col gap-4">
          <div className="flex flex-col gap-4">
            <OverallMetricFilter
              overallMetrics={overallMetrics}
              selectedOverallMetrics={selectedOverallMetrics}
              setSelectedOverallMetrics={setSelectedOverallMetrics}
            />
            {/* <LeaderboardFilter
              groups={groupRows}
              selectedMetrics={selectedMetrics}
              setSelectedMetrics={setSelectedMetrics}
            /> */}
          </div>

          {selectedModels.size === 0 ||
          selectedMetrics.size === 0 ||
          visibleMetrics.length === 0 ? (
            <div className="text-center p-4 text-lg">
              Please select at least one model and one metric to display the data
            </div>
          ) : (
            <>
              {/* Quality metrics table */}
              <QualityMetricsTable
                qualityMetrics={findQualityMetrics()}
                tableHeader={tableHeader}
                selectedModels={selectedModels}
                tableRows={tableRows}
              />

              {/* Main metrics table */}
              <div className="relative flex justify-end mb-6">
                <button
                  className="absolute top-0 right-0 btn btn-ghost btn-circle"
                  title="Export CSV"
                  onClick={() => {
                    // Export the main metrics table as displayed
                    // Build header row

                    const header = [
                      'Attack Categories',
                      ...visibleMetrics.flatMap((metric) => modelOrderByOverallMetric[metric]),
                    ]
                    // Build data rows
                    const rows: (string | number)[][] = []
                    groupEntries.forEach(([group, subGroups]) => {
                      // Group row
                      const allGroupMetrics = Object.values(subGroups).flat()
                      const visibleGroupMetrics = filterMetricsByGroupAndSubgroup(
                        allGroupMetrics,
                        group
                      )
                      if (visibleGroupMetrics.length === 0) return
                      // Group row label
                      const groupRow: (string | number)[] = [group]
                      visibleMetrics.forEach((metric) => {
                        modelOrderByOverallMetric[metric].forEach((col) => {
                          const allMetricsWithName = findAllMetricsForName(metric)
                          const metricsInGroupForThisMetric = visibleGroupMetrics.filter((m) =>
                            allMetricsWithName.includes(m)
                          )
                          const stats = calculateStats(metricsInGroupForThisMetric, col)
                          groupRow.push(
                            !isNaN(stats.avg)
                              ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
                              : 'N/A'
                          )
                        })
                      })
                      rows.push(groupRow)
                      // Subgroup rows
                      let subGroupEntries = Object.entries(subGroups)
                      subGroupEntries.forEach(([subGroup, metrics]) => {
                        const visibleSubgroupMetrics = filterMetricsByGroupAndSubgroup(
                          metrics,
                          group,
                          subGroup
                        )
                        if (visibleSubgroupMetrics.length === 0) return
                        const subGroupRow: (string | number)[] = ['  ' + subGroup] // Indent subgroup
                        visibleMetrics.forEach((metric) => {
                          modelOrderByOverallMetric[metric].forEach((col) => {
                            const allMetricsWithName = findAllMetricsForName(metric)
                            const metricsInSubgroupForThisMetric = visibleSubgroupMetrics.filter(
                              (m) => allMetricsWithName.includes(m)
                            )
                            const stats = calculateStats(metricsInSubgroupForThisMetric, col)
                            subGroupRow.push(
                              !isNaN(stats.avg)
                                ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
                                : 'N/A'
                            )
                          })
                        })
                        rows.push(subGroupRow)
                        // Individual metric rows
                        visibleSubgroupMetrics.forEach((metric) => {
                          const row = tableRows.find((r) => r.metric === metric)
                          if (!row) return
                          const metricRow: (string | number)[] = ['    ' + metric] // Indent metric
                          visibleMetrics.forEach((oMetric) => {
                            if (!findAllMetricsForName(oMetric).includes(metric)) {
                              modelOrderByOverallMetric[oMetric].forEach(() => metricRow.push(''))
                            } else {
                              modelOrderByOverallMetric[oMetric].forEach((col) => {
                                const cell = row[col]
                                metricRow.push(
                                  !isNaN(Number(cell)) ? Number(Number(cell).toFixed(3)) : cell
                                )
                              })
                            }
                          })
                          rows.push(metricRow)
                        })
                      })
                    })
                    // CSV encode
                    const csv = [header, ...rows]
                      .map((row) =>
                        row.map((cell) => `"${String(cell).replace(/"/g, '""')}"`).join(',')
                      )
                      .join('\n')
                    // Download
                    const blob = new Blob([csv], { type: 'text/csv' })
                    const url = URL.createObjectURL(blob)
                    const a = document.createElement('a')
                    a.href = url
                    a.download = 'leaderboard_metrics.csv'
                    document.body.appendChild(a)
                    a.click()
                    document.body.removeChild(a)
                    URL.revokeObjectURL(url)
                  }}
                >
                  <ArrowDownTrayIcon className="h-6 w-6" />
                </button>
              </div>
              <div className="overflow-x-auto max-h-[80vh] overflow-y-auto">
                <table className="table w-full min-w-max border-separate border-spacing-0 border-gray-700 border">
                  <thead>
                    <tr>
                      <th className="sticky left-0 top-0 bg-base-100 z-20 border border-gray-700">
                        Attack Categories
                      </th>
                      {overallMetrics
                        .filter((metric) => selectedOverallMetrics.has(metric))
                        .map((metric) => (
                          <th
                            key={`header-metric-${metric}`}
                            className="sticky top-0 bg-base-100 z-10 text-center text-xs border border-gray-700 select-none"
                            colSpan={modelOrderByOverallMetric[metric].length}
                          >
                            {metric}
                          </th>
                        ))}
                    </tr>
                    <tr>
                      <th className="sticky left-0 top-12 bg-base-100 z-30 border border-gray-700"></th>
                      {overallMetrics
                        .filter((metric) => selectedOverallMetrics.has(metric))
                        .map((metric) => (
                          <React.Fragment key={`header-models-${metric}`}>
                            {modelOrderByOverallMetric[metric].map((model) => {
                              const isSorted = sortState[metric]?.[model]?.direction !== undefined
                              const direction = sortState[metric]?.[model]?.direction || 'desc'
                              return (
                                <th
                                  key={`${metric}-${model}`}
                                  className="sticky top-12 bg-base-100 z-10 text-center text-xs border border-gray-700 cursor-pointer select-none"
                                  onClick={() => handleRowSort(metric, model)}
                                >
                                  {model}
                                  <span className="ml-1">
                                    {isSorted ? (direction === 'asc' ? '↑' : '↓') : '⇅'}
                                  </span>
                                </th>
                              )
                            })}
                          </React.Fragment>
                        ))}
                    </tr>
                  </thead>
                  <tbody>
                    {/* First render each group row */}
                    {groupEntries.map(([group, subGroups]) => {
                      // Skip the "Overall" group completely, keep for now
                      // if (group === OVERALL_ROW) return null

                      // Get all metrics for this group row
                      const allGroupMetrics = Object.values(subGroups).flat()
                      // Filter to only include selected metrics
                      const visibleGroupMetrics = filterMetricsByGroupAndSubgroup(
                        allGroupMetrics,
                        group
                      )

                      // Skip this group row if no metrics are selected
                      if (visibleGroupMetrics.length === 0) return null

                      // Sort subgroups by average if sort config is active
                      let subGroupEntries = Object.entries(subGroups)
                      if (groupSortConfig) {
                        const allMetricsWithName = findAllMetricsForName(
                          groupSortConfig.overallMetric
                        )
                        const getSubGroupAvg = (metrics: string[]) => {
                          const metricsInSubGroupForThisMetric = metrics.filter((m) =>
                            allMetricsWithName.includes(m)
                          )
                          const stats = calculateStats(
                            metricsInSubGroupForThisMetric,
                            groupSortConfig.model
                          )
                          return stats.avg
                        }
                        subGroupEntries = subGroupEntries.sort(([, metricsA], [, metricsB]) => {
                          const avgA = getSubGroupAvg(metricsA)
                          const avgB = getSubGroupAvg(metricsB)
                          if (isNaN(avgA) && isNaN(avgB)) return 0
                          if (isNaN(avgA)) return 1
                          if (isNaN(avgB)) return -1
                          return groupSortConfig.direction === 'asc' ? avgA - avgB : avgB - avgA
                        })
                      }

                      return (
                        <React.Fragment key={group}>
                          {/* Group row with average stats for the entire group */}
                          <tr
                            className="bg-base-200 cursor-pointer hover:bg-base-300"
                            onClick={() =>
                              setOpenGroupRows((prev) => ({ ...prev, [group]: !prev[group] }))
                            }
                          >
                            <td className="sticky left-0 bg-base-200 z-10 font-medium cursor-pointer select-none flex items-center">
                              <span>{openGroupRows[group] ? '▼ ' : '▶ '}</span>
                              <span className="flex-1">{group}</span>
                              {/* Sort icon: only this triggers sort, and shows default if unsorted */}
                              <span
                                className="ml-1 cursor-pointer"
                                onClick={(e) => {
                                  e.stopPropagation()
                                  handleColumnSort(group, null, null)
                                }}
                                title={
                                  getColumnSort(group, null, null)
                                    ? getColumnSort(group, null, null)?.direction === 'asc'
                                      ? 'Sort descending'
                                      : 'Clear sort'
                                    : 'Sort by this row'
                                }
                              >
                                {getColumnSort(group, null, null)
                                  ? getColumnSort(group, null, null)?.direction === 'asc'
                                    ? '→'
                                    : '←'
                                  : '⇆'}
                              </span>
                            </td>
                            {/* For each metric column */}
                            {overallMetrics
                              .filter((metric) => selectedOverallMetrics.has(metric))
                              .map((metric) => {
                                const rowKey = getColumnSortRowKey(group, null, null)
                                return (
                                  <React.Fragment key={`${group}-${metric}`}>
                                    {modelOrderByOverallMetric[metric].map((col: string) => {
                                      const allMetricsWithName = findAllMetricsForName(metric)
                                      const metricsInGroupForThisMetric =
                                        visibleGroupMetrics.filter((m) =>
                                          allMetricsWithName.includes(m)
                                        )
                                      const stats = calculateStats(metricsInGroupForThisMetric, col)
                                      return (
                                        <td
                                          key={`${group}-${metric}-${col}`}
                                          className="font-medium text-center border-gray-700 border"
                                        >
                                          {!isNaN(stats.avg)
                                            ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
                                            : 'N/A'}
                                        </td>
                                      )
                                    })}
                                  </React.Fragment>
                                )
                              })}
                          </tr>

                          {/* Only render subgroups if group row is open */}
                          {openGroupRows[group] &&
                            subGroupEntries.map(([subGroup, metrics]) => {
                              // Filter to only include selected metrics in this subgroup row
                              const visibleSubgroupMetrics = filterMetricsByGroupAndSubgroup(
                                metrics,
                                group,
                                subGroup
                              )

                              // Skip this subgroup row if no metrics are selected
                              if (visibleSubgroupMetrics.length === 0) return null

                              return (
                                <React.Fragment key={`${group}-${subGroup}`}>
                                  {/* Subgroup row with average stats for the subgroup */}
                                  <tr
                                    className="bg-base-100 hover:bg-base-200"
                                    // onClick={() => toggleSubGroup(group, subGroup)}
                                  >
                                    <td className="sticky left-0 bg-base-100 z-10 pl-6 font-medium flex items-center gap-1">
                                      {/* <span>
                                        {openSubGroupRows[group]?.[subGroup] ? '▼ ' : '▶ '}
                                      </span> */}
                                      <span className="flex-1">{subGroup}</span>
                                      <span
                                        className="ml-1 cursor-pointer"
                                        onClick={(e) => {
                                          e.stopPropagation()
                                          handleColumnSort(group, subGroup, null)
                                        }}
                                        title={
                                          getColumnSort(group, subGroup, null)
                                            ? getColumnSort(group, subGroup, null)?.direction ===
                                              'asc'
                                              ? 'Sort descending'
                                              : 'Clear sort'
                                            : 'Sort by this row'
                                        }
                                      >
                                        {getColumnSort(group, subGroup, null)
                                          ? getColumnSort(group, subGroup, null)?.direction ===
                                            'asc'
                                            ? '→'
                                            : '←'
                                          : '⇆'}
                                      </span>
                                    </td>
                                    {/* For each metric column */}
                                    {overallMetrics
                                      .filter((metric) => selectedOverallMetrics.has(metric))
                                      .map((metric) => {
                                        return (
                                          <React.Fragment key={`${group}-${subGroup}-${metric}`}>
                                            {modelOrderByOverallMetric[metric].map(
                                              (col: string) => {
                                                const allMetricsWithName =
                                                  findAllMetricsForName(metric)
                                                const metricsInSubgroupForThisMetric =
                                                  visibleSubgroupMetrics.filter((m) =>
                                                    allMetricsWithName.includes(m)
                                                  )
                                                const stats = calculateStats(
                                                  metricsInSubgroupForThisMetric,
                                                  col
                                                )
                                                return (
                                                  <td
                                                    key={`${group}-${subGroup}-${metric}-${col}`}
                                                    className="font-medium text-center border-gray-700 border"
                                                  >
                                                    {!isNaN(stats.avg)
                                                      ? `${stats.avg.toFixed(3)} ± ${stats.stdDev.toFixed(3)}`
                                                      : 'N/A'}
                                                  </td>
                                                )
                                              }
                                            )}
                                          </React.Fragment>
                                        )
                                      })}
                                  </tr>

                                  {/* Individual metric rows, currently removed in favor of aggregate */}
                                </React.Fragment>
                              )
                            })}
                        </React.Fragment>
                      )
                    })}
                  </tbody>
                </table>
              </div>
            </>
          )}
        </div>
      )}
    </div>
  )
}

export default LeaderboardTable
