<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 tasks = ref<any[]>([])
const selectedTask = ref<any>(null)
const roster = ref<any>(null)
const termId = ref<string>()

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

async function selectTask(task: any) {
  selectedTask.value = task
  detailLoading.value = true
  try {
    roster.value = (await http.get(`/course-selections/teaching-tasks/${task.id}/roster`)).data
  } catch (error) {
    roster.value = null
    ElMessage.error(apiErrorMessage(error))
  } finally {
    detailLoading.value = false
  }
}

async function exportRoster() {
  if (!selectedTask.value) return
  try {
    await downloadApiFile(
      `/course-selections/teaching-tasks/${selectedTask.value.id}/roster/export.xlsx`,
      `教学班名单-${selectedTask.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 loadTasks()
})
</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="loadTasks">刷新</el-button>
    </section>

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

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

      <main class="roster-detail" v-loading="detailLoading">
        <el-empty v-if="!selectedTask" description="请选择一个教学班" />
        <template v-else-if="roster">
          <header class="roster-head">
            <div>
              <span>{{ roster.courseCode }} · {{ roster.taskNumber }}</span>
              <h3>{{ roster.courseName }}教学班名单</h3>
              <p>共 {{ roster.studentCount }} 人 / 容量 {{ 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="联系方式" min-width="210">
              <template #default="{ row }">
                <div class="contact-cell">
                  <span>{{ row.phone || '未填写电话' }}</span>
                  <small>{{ row.email || row.weChat ? [row.email, row.weChat && `微信 ${row.weChat}`].filter(Boolean).join(' · ') : '未填写邮箱或微信' }}</small>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="紧急联系人" min-width="180">
              <template #default="{ row }">
                <div class="contact-cell">
                  <span>{{ row.emergencyContactName || '—' }}<template v-if="row.emergencyContactRelationship">（{{ row.emergencyContactRelationship }}）</template></span>
                  <small>{{ row.emergencyContactPhone || '未填写联系电话' }}</small>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="特殊标记" min-width="210">
              <template #default="{ row }">
                <div class="special-cell">
                  <el-tag v-if="row.specialTags" type="warning" effect="light">{{ row.specialTags }}</el-tag>
                  <span v-else>—</span>
                  <small v-if="row.specialNeeds">{{ row.specialNeeds }}</small>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="名单来源" width="210">
              <template #default="{ row }">{{ row.enrolledAt ? `选课 · ${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; }
.contact-cell, .special-cell { display: grid; gap: 4px; line-height: 1.35; }
.contact-cell small, .special-cell small { color: var(--muted); white-space: normal; }
.special-cell .el-tag { width: fit-content; max-width: 100%; white-space: normal; height: auto; padding-block: 3px; }
@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>
