<!-- 学生列表页（Day 3-6：CRUD + 分页 + 搜索 + Loading + 空状态 + 错误处理）-->
<template>
  <div>
    <NavBar />
    <div class="page">
      <!-- 工具栏：Day 3 搜索 + Day 4 分页 -->
      <div class="toolbar">
        <input v-model="keyword" placeholder="搜索姓名..." @keyup.enter="search" />
        <button class="btn-outline" @click="search">搜索</button>
        <button class="btn-outline" @click="refresh">刷新</button>
        <button v-if="auth.isAdmin" class="btn-add" @click="openForm()">+ 新增</button>
      </div>

      <!-- 错误提示（Day 6） -->
      <div class="error-bar" v-if="error">{{ error }}<button @click="refresh">重试</button></div>

      <!-- Loading 状态（Day 6） -->
      <div class="loading" v-if="loading">加载中...</div>

      <!-- 空状态（Day 6） -->
      <div class="empty" v-else-if="!loading && students.length === 0">
        暂无数据
      </div>

      <!-- 表格 -->
      <div class="table-wrap" v-else>
        <table>
          <thead>
            <tr><th>ID</th><th>姓名</th><th>年龄</th><th>邮箱</th><th>成绩</th><th v-if="auth.isAdmin">操作</th></tr>
          </thead>
          <tbody>
            <tr v-for="s in students" :key="s.id">
              <td>{{ s.id }}</td>
              <td><strong>{{ s.name }}</strong></td>
              <td>{{ s.age }}</td>
              <td>{{ s.email }}</td>
              <td><span class="badge" :class="scoreClass(s.score)">{{ s.score }}</span></td>
              <td v-if="auth.isAdmin">
                <button class="btn-edit" @click="openForm(s)">编辑</button>
                <button class="btn-del" @click="handleDelete(s.id)">删除</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 分页组件（Day 4） -->
      <Pagination :current="page" :totalPages="totalPages" @change="goPage" />

      <!-- 统计卡片 -->
      <div class="stats">
        <div class="stat"><span class="v">{{ statsTotal }}</span><span class="l">总数</span></div>
        <div class="stat"><span class="v">{{ statsExcellent }}</span><span class="l">优秀</span></div>
        <div class="stat"><span class="v">{{ orm }}</span><span class="l">ORM</span></div>
      </div>

      <!-- 新增/编辑弹窗（Day 3 + Day 5：表单 + 提交） -->
      <StudentForm
        :visible="formVisible"
        :student="editTarget"
        :loading="formLoading"
        @close="formVisible = false"
        @submit="handleFormSubmit"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useAuthStore } from '../stores/auth'
import { fetchStudents, fetchExcellent, createStudent, updateStudent, deleteStudent } from '../api/student'
import NavBar from '../components/NavBar.vue'
import Pagination from '../components/Pagination.vue'
import StudentForm from '../components/StudentForm.vue'

const auth = useAuthStore()

// 列表状态
const students = ref([])
const keyword = ref('')
const page = ref(0)
const size = ref(10)
const totalPages = ref(0)
const loading = ref(false)
const error = ref('')
const statsTotal = ref(0)
const statsExcellent = ref(0)
const orm = ref('--')

// 表单状态
const formVisible = ref(false)
const editTarget = ref(null)
const formLoading = ref(false)

function scoreClass(s) {
  if (s >= 90) return 'badge-excellent'
  if (s >= 80) return 'badge-good'
  if (s >= 60) return 'badge-normal'
  return 'badge-poor'
}

async function loadData() {
  loading.value = true; error.value = ''
  try {
    const result = await fetchStudents(keyword.value || undefined, page.value, size.value)
    students.value = result.data || []
    statsTotal.value = result.extra?.total ?? students.value.length
    if (result.extra?.pages != null) totalPages.value = result.extra.pages
    else totalPages.value = Math.ceil((result.extra?.total ?? students.value.length) / size.value)
    orm.value = result.extra?.orm ?? '--'
    const exc = await fetchExcellent(85)
    statsExcellent.value = exc.data ?? 0
  } catch (e) {
    error.value = e.message
    students.value = []
  } finally {
    loading.value = false
  }
}

function search() { page.value = 0; loadData() }
function refresh() { keyword.value = ''; page.value = 0; loadData() }
function goPage(p) { page.value = p; loadData() }

function openForm(student) {
  editTarget.value = student || null
  formVisible.value = true
}

async function handleFormSubmit(data) {
  formLoading.value = true
  try {
    if (data.id) {
      await updateStudent(data.id, data)
    } else {
      await createStudent(data)
    }
    formVisible.value = false
    loadData()
  } catch (e) {
    alert(e.message)
  } finally {
    formLoading.value = false
  }
}

async function handleDelete(id) {
  if (!confirm('确认删除？')) return
  try {
    await deleteStudent(id)
    loadData()
  } catch (e) {
    alert(e.message)
  }
}

onMounted(loadData)
</script>

<style scoped>
.page { max-width: 1000px; margin: 30px auto; padding: 0 20px; }

/* 工具栏 */
.toolbar { display: flex; gap: 10px; margin-bottom: 16px; background: #fff; padding: 14px 18px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.toolbar input { flex: 1; padding: 9px 12px; border: 1.5px solid #ddd; border-radius: 8px; font-size: 0.93em; }
.toolbar input:focus { outline: none; border-color: #667eea; }
.btn-outline { padding: 9px 18px; border: 1.5px solid #667eea; background: #fff; color: #667eea; border-radius: 8px; cursor: pointer; font-size: 0.9em; }
.btn-outline:hover { background: #f0f2ff; }
.btn-add { padding: 9px 22px; background: #667eea; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-size: 0.9em; }
.btn-add:hover { background: #5a6fd6; }

/* 错误/加载/空状态 */
.error-bar { background: #fff3cd; color: #856404; padding: 12px 18px; border-radius: 8px; margin-bottom: 14px; display: flex; justify-content: space-between; }
.error-bar button { background: none; border: none; color: #856404; text-decoration: underline; cursor: pointer; }
.loading, .empty { text-align: center; padding: 80px 0; color: #fff; font-size: 1.1em; }

/* 表格 */
.table-wrap { background: #fff; border-radius: 10px; padding: 0 20px 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 0.93em; }
thead th { text-align: left; padding: 14px 10px; border-bottom: 2px solid #667eea; color: #667eea; font-weight: 600; white-space: nowrap; }
tbody td { padding: 12px 10px; border-bottom: 1px solid #f0f0f0; }
tbody tr:hover { background: #f8f9ff; }

/* 成绩徽章 */
.badge { display: inline-block; padding: 3px 10px; border-radius: 12px; font-size: 0.82em; font-weight: 600; color: #fff; }
.badge-excellent { background: #2ecc71; }
.badge-good { background: #3498db; }
.badge-normal { background: #f39c12; }
.badge-poor { background: #e74c3c; }

/* 操作按钮 */
.btn-edit { padding: 4px 12px; background: #2ecc71; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.82em; margin-right: 6px; }
.btn-edit:hover { background: #27ae60; }
.btn-del { padding: 4px 12px; background: #e74c3c; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 0.82em; }
.btn-del:hover { background: #c0392b; }

/* 统计 */
.stats { background: #fff; border-radius: 10px; padding: 16px 20px; display: flex; gap: 14px; margin-top: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.stat { flex: 1; text-align: center; padding: 14px 10px; border-radius: 8px; background: linear-gradient(135deg, #667eea, #764ba2); }
.v { display: block; font-size: 1.5em; font-weight: 700; color: #fff; }
.l { display: block; font-size: 0.78em; color: rgba(255,255,255,0.8); margin-top: 3px; }

@media (max-width: 600px) {
  .toolbar { flex-wrap: wrap; }
  .stats { flex-direction: column; }
}
</style>
