<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { Refresh, Search } from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'

const loading = ref(false)
const payload = ref<any>({ student: null, plan: null })
const keyword = ref('')
const statusFilter = ref('All')

const statusLabels: Record<string, string> = {
  Completed: '已完成',
  InProgress: '在读',
  Retaking: '重修中',
  Failed: '未通过',
  Pending: '待完成',
  NotStarted: '未修读',
}
const typeLabels: Record<string, string> = {
  Required: '指定必修',
  Elective: '组内选修',
}
const examStatusLabels: Record<string, string> = {
  Normal: '正常',
  Absent: '缺考',
  Deferred: '缓考',
  Exempt: '免修',
}

const plan = computed(() => payload.value.plan)
const student = computed(() => payload.value.student)
const visibleModules = computed(() => {
  const normalizedKeyword = keyword.value.trim().toLowerCase()
  return (plan.value?.modules ?? [])
    .map((module: any) => ({
      ...module,
      courses: module.courses.filter((course: any) => {
        const matchesKeyword = !normalizedKeyword ||
          `${course.courseCode} ${course.courseName} ${course.categoryName ?? ''}`
            .toLowerCase()
            .includes(normalizedKeyword)
        const matchesStatus = statusFilter.value === 'All' ||
          statusFilter.value === 'InProgress' &&
            ['InProgress', 'Retaking'].includes(course.status) ||
          statusFilter.value === 'Failed' &&
            course.hasFailedAttempt && !course.hasPassedAttempt ||
          course.status === statusFilter.value
        return matchesKeyword && matchesStatus
      }),
    }))
    .filter((module: any) => module.courses.length > 0)
})
const visibleCourseCount = computed(() =>
  visibleModules.value.reduce(
    (sum: number, module: any) => sum + module.courses.length,
    0,
  ))

async function load() {
  loading.value = true
  try {
    payload.value = (await http.get('/student/curriculum-plan')).data
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}

function resultText(course: any) {
  const result = course.latestResult
  if (!result) return '暂无成绩'
  if (result.examStatus === 'Exempt') return `${result.termName} · 免修通过`
  if (result.totalScore != null) {
    return `${result.termName} · ${result.totalScore} 分 · 绩点 ${result.gradePoint ?? '—'}`
  }
  return `${result.termName} · ${examStatusLabels[result.examStatus] ?? '待完成'}`
}

onMounted(load)
</script>

<template>
  <div class="page-stack curriculum-ledger-page" v-loading="loading">
    <section class="page-intro">
      <div>
        <span class="section-kicker">MY CURRICULUM</span>
        <h2>我的培养方案</h2>
        <p>按培养方案核对已完成、在读、重修与尚未通过的课程。</p>
      </div>
      <div class="page-actions">
        <el-button @click="$router.push('/academic-planning')">学业规划与毕业模拟</el-button>
        <el-button :icon="Refresh" @click="load">刷新进度</el-button>
      </div>
    </section>

    <section v-if="student" class="student-plan-head">
      <div class="student-plan-identity">
        <span>{{ student.enrollmentYear }} 级 · {{ student.collegeName }}</span>
        <h3>{{ student.name }}</h3>
        <p>{{ student.studentNumber }} · {{ student.majorName }} · {{ student.className }}</p>
      </div>
      <div v-if="plan" class="plan-seal">
        <span>适用方案</span>
        <b>{{ plan.version }}</b>
        <small>{{ plan.schoolingYears }} 年制</small>
      </div>
    </section>

    <el-empty
      v-if="student && !plan && !loading"
      :description="payload.message || '尚未匹配已发布的培养方案'"
      class="plan-empty"
    />

    <template v-if="plan">
      <section class="plan-brief">
        <div>
          <span>{{ plan.majorName }}</span>
          <h3>{{ plan.name }}</h3>
          <p>{{ plan.description || '本页仅展示已正式发布的培养方案及本人实时修读情况。' }}</p>
        </div>
        <div class="credit-progress">
          <div>
            <span>已完成学分</span>
            <b>{{ plan.summary.completedCredits }}</b>
            <small>/ {{ plan.totalCredits }}</small>
          </div>
          <div class="credit-track" aria-label="培养方案学分完成比例">
            <i :style="{ width: `${plan.summary.completionRate}%` }" />
          </div>
          <p>完成度 {{ plan.summary.completionRate }}%</p>
        </div>
      </section>

      <section class="progress-index" aria-label="课程进度摘要">
        <div>
          <span>方案课程</span>
          <b>{{ plan.summary.courseCount }}</b>
          <small>门</small>
        </div>
        <div class="completed">
          <span>已完成</span>
          <b>{{ plan.summary.completedCourseCount }}</b>
          <small>门</small>
        </div>
        <div class="studying">
          <span>当前在读</span>
          <b>{{ plan.summary.inProgressCourseCount }}</b>
          <small>门</small>
        </div>
        <div class="failed">
          <span>未通过记录</span>
          <b>{{ plan.summary.failedCourseCount }}</b>
          <small>门</small>
        </div>
      </section>

      <section class="ledger-tools">
        <el-input
          v-model="keyword"
          :prefix-icon="Search"
          clearable
          placeholder="搜索课程编码、名称或分类"
        />
        <el-select v-model="statusFilter" aria-label="按修读状态筛选">
          <el-option label="全部修读状态" value="All" />
          <el-option label="已完成" value="Completed" />
          <el-option label="在读（含重修）" value="InProgress" />
          <el-option label="未通过（含重修）" value="Failed" />
          <el-option label="待完成" value="Pending" />
          <el-option label="未修读" value="NotStarted" />
        </el-select>
        <span>当前显示 {{ visibleCourseCount }} 门</span>
      </section>

      <section class="curriculum-ledger">
        <article v-for="module in visibleModules" :key="module.id" class="module-sheet">
          <header>
            <div class="module-code">{{ module.code }}</div>
            <div>
              <span>培养模块</span>
              <h3>{{ module.name }}</h3>
            </div>
            <p>要求学分 <b>{{ module.requiredCredits }}</b></p>
          </header>

          <div class="course-ledger-head" aria-hidden="true">
            <span>建议学期</span>
            <span>课程</span>
            <span>课程要求</span>
            <span>学分 / 学时</span>
            <span>本人进度</span>
          </div>
          <div
            v-for="course in module.courses"
            :key="course.id"
            class="course-ledger-row"
          >
            <div class="semester-cell">
              <span>第</span><b>{{ course.recommendedSemester }}</b><span>学期</span>
            </div>
            <div class="ledger-course">
              <span>{{ course.courseCode }} · {{ course.categoryName || '未分类' }}</span>
              <h4>{{ course.courseName }}</h4>
              <p v-if="course.notes">{{ course.notes }}</p>
            </div>
            <div class="requirement-cell">
              <b>{{ typeLabels[course.type] }}</b>
              <span>{{ course.nature === 'Practice' ? '实践课程' : '计划课程' }}</span>
            </div>
            <div class="credit-cell">
              <b>{{ course.credits }}</b><span>学分</span>
              <small>{{ course.totalHours }} 学时</small>
            </div>
            <div class="progress-cell">
              <i :class="course.status">{{ statusLabels[course.status] }}</i>
              <span>{{ resultText(course) }}</span>
              <small
                v-if="course.hasFailedAttempt && course.status !== 'Failed'"
                class="failed-history"
              >有未通过记录</small>
            </div>
          </div>
        </article>

        <el-empty
          v-if="!visibleModules.length"
          description="没有符合筛选条件的课程"
        />
      </section>
    </template>
  </div>
</template>

<style scoped>
.student-plan-head {
  min-height: 138px;
  display: grid;
  grid-template-columns: 1fr 168px;
  color: white;
  border: 1px solid #21396f;
  background:
    linear-gradient(rgba(255,255,255,.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.035) 1px, transparent 1px),
    linear-gradient(112deg, #17295c, #273f7b 70%, #146f70);
  background-size: 22px 22px, 22px 22px, auto;
}
.student-plan-identity {
  align-self: center;
  padding: 25px 30px;
}
.student-plan-identity > span,
.plan-seal > span {
  color: #63d8c6;
  font: 700 10px/1.2 Consolas, monospace;
  letter-spacing: .11em;
}
.student-plan-identity h3 {
  margin: 9px 0 6px;
  font-family: "STZhongsong", "Songti SC", serif;
  font-size: 27px;
  letter-spacing: .08em;
}
.student-plan-identity p {
  margin: 0;
  color: #c6cee5;
  font-size: 11px;
}
.plan-seal {
  margin: 22px;
  display: grid;
  place-content: center;
  text-align: center;
  border: 1px solid rgba(255,255,255,.3);
  outline: 1px solid rgba(255,255,255,.12);
  outline-offset: -6px;
  background: rgba(9,24,60,.25);
}
.plan-seal b {
  margin: 8px 0 5px;
  font-family: "STZhongsong", "Songti SC", serif;
  font-size: 20px;
}
.plan-seal small { color: #b7c2dd; font-size: 10px; }
.plan-empty {
  min-height: 300px;
  border: 1px solid var(--line);
  background: white;
}
.plan-brief {
  min-height: 128px;
  padding: 24px 28px;
  display: grid;
  grid-template-columns: 1fr minmax(300px, 430px);
  gap: 36px;
  align-items: center;
  border: 1px solid var(--line);
  background: white;
}
.plan-brief > div:first-child > span {
  color: var(--teal);
  font-size: 10px;
  font-weight: 700;
}
.plan-brief h3 {
  margin: 7px 0 7px;
  font-family: "STZhongsong", "Songti SC", serif;
  font-size: 20px;
}
.plan-brief p {
  margin: 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.7;
}
.credit-progress > div:first-child {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.credit-progress span { color: var(--muted); font-size: 10px; }
.credit-progress b {
  margin-left: auto;
  color: var(--indigo);
  font: 700 29px/1 Consolas, monospace;
}
.credit-progress small { color: var(--muted); font-size: 11px; }
.credit-track {
  height: 7px;
  margin: 11px 0 7px;
  background: #e8ebf1;
  overflow: hidden;
}
.credit-track i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #243a78, #078276);
}
.credit-progress > p { text-align: right; font: 700 10px/1.2 Consolas, monospace; }
.progress-index {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--line);
  background: white;
}
.progress-index > div {
  min-height: 78px;
  padding: 16px 20px;
  display: flex;
  align-items: baseline;
  gap: 5px;
  border-right: 1px solid var(--line);
  box-shadow: inset 0 3px #8c96aa;
}
.progress-index > div:last-child { border-right: none; }
.progress-index > .completed { box-shadow: inset 0 3px #087f73; }
.progress-index > .studying { box-shadow: inset 0 3px #315f9a; }
.progress-index > .failed { box-shadow: inset 0 3px #b34e48; }
.progress-index span { color: var(--muted); font-size: 10px; }
.progress-index b {
  margin-left: auto;
  color: var(--ink);
  font: 700 25px/1 Consolas, monospace;
}
.progress-index small { color: var(--muted); font-size: 9px; }
.ledger-tools {
  min-height: 68px;
  padding: 13px 16px;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--line);
  background: #fbfcfd;
}
.ledger-tools .el-input { width: min(360px, 42vw); }
.ledger-tools .el-select { width: 190px; }
.ledger-tools > span {
  margin-left: auto;
  color: var(--muted);
  font-size: 11px;
}
.curriculum-ledger { display: grid; gap: 14px; }
.module-sheet {
  border: 1px solid var(--line);
  background: white;
  overflow: hidden;
}
.module-sheet > header {
  min-height: 74px;
  padding: 0 20px 0 0;
  display: grid;
  grid-template-columns: 82px 1fr auto;
  align-items: center;
  border-bottom: 1px solid var(--line);
  background: #f7f9fc;
}
.module-code {
  align-self: stretch;
  display: grid;
  place-items: center;
  color: white;
  background: #233876;
  font: 700 12px/1 Consolas, monospace;
  letter-spacing: .06em;
}
.module-sheet header > div:nth-child(2) { padding-left: 18px; }
.module-sheet header span { color: var(--muted); font-size: 9px; }
.module-sheet header h3 { margin: 5px 0 0; font-size: 16px; }
.module-sheet header p { margin: 0; color: var(--muted); font-size: 10px; }
.module-sheet header p b { color: var(--indigo); font: 700 17px/1 Consolas, monospace; }
.course-ledger-head,
.course-ledger-row {
  display: grid;
  grid-template-columns: 105px minmax(260px, 1.5fr) minmax(120px, .7fr) 120px minmax(220px, 1fr);
}
.course-ledger-head {
  min-height: 38px;
  align-items: center;
  color: #727b8d;
  background: #fcfcfd;
  border-bottom: 1px solid #e9ecf1;
  font-size: 9px;
}
.course-ledger-head span,
.course-ledger-row > div { padding: 0 16px; border-right: 1px solid #edf0f4; }
.course-ledger-head span:last-child,
.course-ledger-row > div:last-child { border-right: none; }
.course-ledger-row {
  min-height: 92px;
  border-bottom: 1px solid #edf0f4;
}
.course-ledger-row:last-child { border-bottom: none; }
.course-ledger-row > div {
  display: grid;
  align-content: center;
}
.semester-cell {
  grid-template-columns: auto auto auto;
  place-content: center;
  align-items: baseline;
  gap: 3px;
  color: var(--muted);
}
.semester-cell span { font-size: 9px; }
.semester-cell b { color: var(--indigo); font: 700 21px/1 Consolas, monospace; }
.ledger-course > span { color: var(--teal); font-size: 9px; }
.ledger-course h4 { margin: 6px 0 0; font-size: 14px; }
.ledger-course p { margin: 5px 0 0; color: var(--muted); font-size: 9px; }
.requirement-cell,
.credit-cell { gap: 5px; }
.requirement-cell b { font-size: 11px; }
.requirement-cell span,
.credit-cell span,
.credit-cell small { color: var(--muted); font-size: 9px; }
.credit-cell b { color: var(--ink); font: 700 17px/1 Consolas, monospace; }
.progress-cell { gap: 6px; }
.progress-cell > i {
  width: max-content;
  min-width: 58px;
  padding: 4px 8px;
  border-left: 3px solid #8993a5;
  color: #5e687a;
  background: #f1f3f6;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
}
.progress-cell > i.Completed { color: #087f73; border-color: #087f73; background: #eaf6f3; }
.progress-cell > i.InProgress { color: #315f9a; border-color: #315f9a; background: #edf3fa; }
.progress-cell > i.Retaking { color: #a6671b; border-color: #c78724; background: #fbf4e8; }
.progress-cell > i.Failed { color: #a43f3b; border-color: #b34e48; background: #faeeee; }
.progress-cell > i.Pending { color: #79579a; border-color: #8062a0; background: #f4eff8; }
.progress-cell > span { color: var(--muted); font-size: 9px; }
.failed-history { color: #a43f3b; font-size: 9px; }

@media (max-width: 900px) {
  .plan-brief { grid-template-columns: 1fr; gap: 20px; }
  .course-ledger-head { display: none; }
  .course-ledger-row {
    grid-template-columns: 76px 1fr 150px;
    min-height: 112px;
  }
  .requirement-cell,
  .credit-cell { display: none !important; }
}

@media (max-width: 600px) {
  .student-plan-head { grid-template-columns: 1fr; }
  .plan-seal { min-height: 86px; margin-top: 0; }
  .progress-index { grid-template-columns: 1fr 1fr; }
  .progress-index > div:nth-child(2) { border-right: none; }
  .progress-index > div:nth-child(-n + 2) { border-bottom: 1px solid var(--line); }
  .ledger-tools { align-items: stretch; flex-direction: column; }
  .ledger-tools .el-input,
  .ledger-tools .el-select { width: 100%; }
  .ledger-tools > span { margin-left: 0; }
  .module-sheet > header { grid-template-columns: 62px 1fr; }
  .module-sheet header > p { display: none; }
  .course-ledger-row {
    grid-template-columns: 62px 1fr;
    min-height: 0;
  }
  .semester-cell { padding: 12px 8px !important; }
  .ledger-course { padding: 14px !important; }
  .progress-cell {
    grid-column: 1 / -1;
    padding: 11px 14px !important;
    border-top: 1px dashed #dfe4eb;
    border-right: none !important;
  }
}
</style>
