<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { Download, Refresh } from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'
import { downloadApiFile } from '../api/excel'
import { academicTermLabel, academicTermOptionClass, defaultAcademicTermId } from '../utils/academicTerms'

const loading = ref(false)
const detailLoading = ref(false)
const terms = ref<any[]>([])
const offerings = ref<any[]>([])
const selectedOffering = ref<any>(null)
const roster = ref<any>(null)
const termId = ref<string>()

async function loadOfferings() {
  loading.value = true
  try {
    offerings.value = (await http.get('/course-selections/my-offerings', {
      params: { academicTermId: termId.value || undefined },
    })).data
    const preferred = offerings.value.find((item: any) => item.id === selectedOffering.value?.id)
      ?? offerings.value[0]
    if (preferred) await selectOffering(preferred)
    else {
      selectedOffering.value = null
      roster.value = null
    }
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}

async function selectOffering(offering: any) {
  selectedOffering.value = offering
  detailLoading.value = true
  try {
    roster.value = (await http.get(`/course-selections/offerings/${offering.id}/roster`)).data
  } catch (error) {
    roster.value = null
    ElMessage.error(apiErrorMessage(error))
  } finally {
    detailLoading.value = false
  }
}

async function exportRoster() {
  if (!selectedOffering.value) return
  try {
    await downloadApiFile(
      `/course-selections/offerings/${selectedOffering.value.id}/roster/export.xlsx`,
      `选课名单-${selectedOffering.value.taskNumber}.xlsx`,
    )
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}

onMounted(async () => {
  terms.value = (await http.get('/base-data/terms')).data
  termId.value = defaultAcademicTermId(terms.value)
  await loadOfferings()
})
</script>

<template>
  <div class="page-stack roster-page">
    <section class="page-intro">
      <div>
        <span class="section-kicker">ENROLLMENT ROSTER</span>
        <h2>选课名单</h2>
        <p>查看本人授课班级的选课学生名单，支持 Excel 导出。</p>
      </div>
      <el-button :icon="Refresh" @click="loadOfferings">刷新</el-button>
    </section>

    <section class="roster-toolbar">
      <el-select v-model="termId" clearable placeholder="全部学期" @change="loadOfferings">
        <el-option v-for="term in terms" :key="term.id" :label="academicTermLabel(term)" :value="term.id" :class="academicTermOptionClass(term)" />
      </el-select>
      <span>共 {{ offerings.length }} 个教学班</span>
    </section>

    <section class="roster-workspace" v-loading="loading">
      <aside class="roster-task-list">
        <button
          v-for="offering in offerings"
          :key="offering.id"
          type="button"
          :class="{ active: selectedOffering?.id === offering.id }"
          @click="selectOffering(offering)"
        >
          <span>{{ offering.courseCode }} · {{ offering.taskNumber }}</span>
          <b>{{ offering.courseName }}</b>
          <small>{{ offering.termName }} · {{ offering.roundName }}</small>
          <i>{{ offering.enrolledCount }} / {{ offering.capacity }} 人</i>
        </button>
        <el-empty v-if="!offerings.length" description="当前学期没有选课教学班" />
      </aside>

      <main class="roster-detail" v-loading="detailLoading">
        <el-empty v-if="!selectedOffering" description="请选择一个教学班" />
        <template v-else-if="roster">
          <header class="roster-head">
            <div>
              <span>{{ roster.courseCode }} · {{ roster.taskNumber }}</span>
              <h3>{{ roster.courseName }}选课名单</h3>
              <p>已选 {{ roster.enrolledCount }} 人 / 容量 {{ roster.capacity }} 人</p>
            </div>
            <el-button :icon="Download" @click="exportRoster">导出 Excel</el-button>
          </header>
          <el-table :data="roster.students" class="data-table">
            <el-table-column label="学号" width="135">
              <template #default="{ row }"><span class="registry-number">{{ row.studentNumber }}</span></template>
            </el-table-column>
            <el-table-column prop="name" label="姓名" min-width="100" />
            <el-table-column prop="className" label="班级" min-width="130" />
            <el-table-column prop="majorName" label="专业" min-width="150" />
            <el-table-column label="选课时间" width="170">
              <template #default="{ row }">{{ new Date(row.enrolledAt).toLocaleString('zh-CN') }}</template>
            </el-table-column>
          </el-table>
        </template>
      </main>
    </section>
  </div>
</template>

<style scoped>
.roster-toolbar {
  min-height: 56px; padding: 10px 16px;
  display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--line); background: #fbfcfd;
}
.roster-toolbar .el-select { width: 260px; }
.roster-toolbar > span { color: var(--muted); font-size: 12px; }
.roster-workspace { display: grid; grid-template-columns: 280px minmax(0, 1fr); min-height: 420px; border: 1px solid var(--line); background: white; }
.roster-task-list { border-right: 1px solid var(--line); overflow-y: auto; max-height: 600px; }
.roster-task-list button {
  display: grid; gap: 3px; width: 100%; padding: 14px 16px; border: none; border-bottom: 1px solid #edf0f4;
  background: none; cursor: pointer; text-align: left; transition: background .15s;
}
.roster-task-list button:hover { background: #f5f7fa; }
.roster-task-list button.active { background: #e9f3f5; border-left: 3px solid #176b87; }
.roster-task-list button > span { color: var(--teal); font: 700 10px/1.2 Consolas, monospace; }
.roster-task-list button > b { font-size: 14px; }
.roster-task-list button > small { color: var(--muted); font-size: 11px; }
.roster-task-list button > i { color: var(--indigo); font-size: 10px; font-weight: 700; }
.roster-detail { min-height: 420px; }
.roster-head {
  padding: 18px 22px; display: flex; align-items: center; justify-content: space-between; gap: 16px;
  border-bottom: 1px solid var(--line); background: #f8fafb;
}
.roster-head h3 { margin: 5px 0 4px; font-size: 18px; }
.roster-head p { color: var(--muted); font-size: 12px; margin: 0; }
.roster-head span { color: var(--teal); font-size: 10px; font-weight: 700; }
@media (max-width: 760px) {
  .roster-workspace { grid-template-columns: 1fr; }
  .roster-task-list { max-height: 220px; border-right: none; border-bottom: 1px solid var(--line); }
}
</style>
