<template>
  <div class="summary-table-card">
    <div class="summary-table-scroll">
      <table class="summary-table">
        <thead>
          <tr>
            <th class="index-col">序号</th>
            <th>姓名</th>
            <th v-for="column in columns" :key="column.key">
              <button
                v-if="column.sortable !== false"
                class="sort-btn"
                type="button"
                @click="toggleSort(column.key)"
              >
                {{ column.label }}
                <span class="sort-icon" :class="{ active: sortKey === column.key }">
                  {{ getSortIcon(column.key) }}
                </span>
              </button>
              <template v-else>{{ column.label }}</template>
            </th>
          </tr>
        </thead>

        <tbody>
          <tr v-for="(student, index) in sortedRows" :key="student.id">
            <td class="index-col">{{ index + 1 }}</td>
            <td>
              <div class="student-info">
                <img class="student-avatar" :src="student.avatar" :alt="student.name" />
                <span class="student-name">{{ student.name }}</span>
                <span class="gender-icon" :class="student.gender">
                  {{ student.gender === 'boy' ? '♂' : '♀' }}
                </span>
              </div>
            </td>
            <td v-for="column in columns" :key="column.key">
              {{ formatMetric(student.metrics[column.key], column) }}
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <table v-if="averageRow" class="summary-table average-table">
      <tbody>
        <tr class="average-row">
          <td class="index-col">平均</td>
          <td></td>
          <td v-for="column in columns" :key="column.key">
            {{ formatMetric(averageRow[column.key], column) }}
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

type Gender = 'boy' | 'girl'

export type StudentSummaryRow = {
  id: number
  name: string
  gender: Gender
  avatar: string
  metrics: Record<string, number>
}

export type StudentSummaryColumn = {
  key: string
  label: string
  type?: 'number' | 'duration'
  sortable?: boolean
}

type SortOrder = 'asc' | 'desc'

const props = defineProps<{
  columns: StudentSummaryColumn[]
  rows: StudentSummaryRow[]
  averageRow?: Record<string, number>
}>()

const sortKey = ref(props.columns[0]?.key ?? '')
const sortOrder = ref<SortOrder>('desc')

const sortedRows = computed(() => {
  const orderFactor = sortOrder.value === 'asc' ? 1 : -1

  return [...props.rows].sort((a, b) => {
    return (getMetricValue(a, sortKey.value) - getMetricValue(b, sortKey.value)) * orderFactor
  })
})

function getMetricValue(row: StudentSummaryRow, key: string) {
  return row.metrics[key] ?? 0
}

function toggleSort(key: string) {
  if (sortKey.value === key) {
    sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
    return
  }

  sortKey.value = key
  sortOrder.value = 'desc'
}

function getSortIcon(key: string) {
  if (sortKey.value !== key) return '◆'
  return sortOrder.value === 'asc' ? '▲' : '▼'
}

function formatMetric(value: number | undefined, column: StudentSummaryColumn) {
  const safeValue = value ?? 0
  if (column.type === 'duration') return formatDuration(safeValue)
  return safeValue
}

function formatDuration(totalSeconds: number) {
  const hours = Math.floor(totalSeconds / 3600)
  const minutes = Math.floor((totalSeconds % 3600) / 60)
  const seconds = totalSeconds % 60

  return [hours, minutes, seconds].map(value => String(value).padStart(2, '0')).join(':')
}
</script>

<style scoped lang="scss">
.summary-table-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.88);
}

.summary-table-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  scrollbar-width: none;

  &::-webkit-scrollbar {
    display: none;
  }
}

.average-table {
  flex-shrink: 0;
  background: rgba(242, 247, 255, 0.96);
}

.summary-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;

  th,
  td {
    height: 82px;
    border-bottom: 1px solid rgba(225, 230, 239, 0.52);
    color: #1f2937;
    font-size: 26px;
    font-weight: 400;
    text-align: left;
    vertical-align: middle;
  }

  th {
    position: sticky;
    top: 0;
    z-index: 2;
    height: 64px;
    color: #7d8796;
    font-size: 22px;
    background: rgba(247, 249, 253, 0.86);
  }

  th:nth-child(2),
  td:nth-child(2) {
    width: 18%;
  }

  th:nth-child(n + 3),
  td:nth-child(n + 3) {
    min-width: 0;
  }
}

.index-col {
  width: 86px;
  padding-left: 34px;
}

.sort-btn {
  display: inline-flex;
  align-items: center;
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font: inherit;
  padding: 0;
}

.sort-icon {
  margin-left: 6px;
  color: #c6ccd6;
  font-size: 13px;
  vertical-align: middle;

  &.active {
    color: #7d8796;
  }
}

.student-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.student-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  object-fit: cover;
}

.student-name {
  color: #172033;
}

.gender-icon {
  font-size: 22px;
  font-weight: 600;

  &.boy {
    color: #27a9e8;
  }

  &.girl {
    color: #ef7aa9;
  }
}

.average-row {
  td {
    border-bottom: none;
    color: #4f8bd3;
    background: transparent;
  }
}
</style>
