<script setup lang="ts">
import { computed, onMounted, onUnmounted, reactive, ref, watch } from 'vue'
import { Check, DocumentChecked, Plus, Refresh, Stamp } from '@element-plus/icons-vue'
import http, { apiErrorMessage } from '../api/http'
import { useAuthStore } from '../stores/auth'

const auth = useAuthStore()
const isStudent = computed(() => auth.user?.roles.includes('Student') ?? false)
const isPublisher = computed(() =>
  auth.user?.roles.some((role) => ['SuperAdmin', 'AcademicAdmin'].includes(role)) ?? false)
const batches = ref<any[]>([])
const selected = ref<any | null>(null)
const myResult = ref<any | null>(null)
const loading = ref(false)
const createDialog = ref(false)
const decisionDialog = ref(false)
const decisionTarget = ref<any | null>(null)
const keyword = ref('')
const conclusionFilter = ref('')
const resultPage = ref(1)
const resultPageSize = 20
const resultRequestId = ref(0)
let filterTimer: ReturnType<typeof setTimeout> | undefined
const batchForm = reactive({
  name: '2030届本科生毕业资格审核',
  graduationYear: 2030,
  enrollmentYear: 2026,
  notes: '',
})
const decisionForm = reactive({ conclusion: 'Ineligible', comment: '' })
const statusLabels: Record<string, string> = { Draft: '审核中', Published: '已发布' }
const conclusionLabels: Record<string, string> = { Eligible: '符合毕业条件', Ineligible: '暂不符合' }
const resultItems = computed(() => selected.value?.results?.items ?? [])
const resultTotal = computed(() => selected.value?.results?.total ?? 0)

function percent(earned: number, required: number) {
  if (!required) return 0
  return Math.min(100, Math.round((earned / required) * 100))
}
function dateText(value?: string) {
  if (!value) return '—'
  return new Intl.DateTimeFormat('zh-CN', {
    year: 'numeric', month: '2-digit', day: '2-digit',
    hour: '2-digit', minute: '2-digit', hour12: false,
  }).format(new Date(value))
}
async function load() {
  loading.value = true
  try {
    if (isStudent.value) {
      myResult.value = (await http.get('/graduation-audits/my-result')).data
      return
    }
    batches.value = (await http.get('/graduation-audits/batches')).data
    const batch = batches.value.find((x) => x.id === selected.value?.id) ?? batches.value[0]
    if (batch) await selectBatch(batch.id)
    else selected.value = null
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}
async function selectBatch(id: string) {
  resultPage.value = 1
  await loadBatch(id)
}
async function loadBatch(id = selected.value?.id) {
  if (!id) return
  const requestId = ++resultRequestId.value
  loading.value = true
  try {
    const response = await http.get(`/graduation-audits/batches/${id}`, {
      params: {
        page: resultPage.value,
        pageSize: resultPageSize,
        keyword: keyword.value.trim() || undefined,
        conclusion: conclusionFilter.value || undefined,
      },
    })
    if (requestId === resultRequestId.value) selected.value = response.data
  } catch (error) {
    if (requestId === resultRequestId.value) ElMessage.error(apiErrorMessage(error))
  } finally {
    if (requestId === resultRequestId.value) loading.value = false
  }
}
async function createBatch() {
  if (!batchForm.name.trim()) return
  try {
    const response = await http.post('/graduation-audits/batches', batchForm)
    createDialog.value = false
    await http.post(`/graduation-audits/batches/${response.data.id}/calculate`)
    ElMessage.success('审核批次已建立，并完成首次资格计算。')
    await load()
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}
async function calculate() {
  try {
    await ElMessageBox.confirm('重新计算会覆盖当前人工调整结果，是否继续？', '重新计算资格', {
      type: 'warning', confirmButtonText: '重新计算',
    })
    await http.post(`/graduation-audits/batches/${selected.value.id}/calculate`)
    ElMessage.success('已按最新培养方案与发布成绩重新计算。')
    await load()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}
function openDecision(row: any) {
  decisionTarget.value = row
  decisionForm.conclusion = row.conclusion
  decisionForm.comment = row.reviewComment ?? ''
  decisionDialog.value = true
}
async function saveDecision() {
  if (decisionForm.comment.trim().length < 5) {
    ElMessage.warning('人工复核意见至少填写 5 个字。')
    return
  }
  try {
    await http.put(`/graduation-audits/results/${decisionTarget.value.id}`, decisionForm)
    decisionDialog.value = false
    ElMessage.success('人工复核结论已保存。')
    await loadBatch()
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  }
}
async function publish() {
  try {
    await ElMessageBox.confirm(
      '发布后结果不可修改；符合条件的在籍学生将同步为“毕业”状态。',
      '发布毕业审核结果',
      { type: 'warning', confirmButtonText: '确认发布' },
    )
    await http.post(`/graduation-audits/batches/${selected.value.id}/publish`)
    ElMessage.success('毕业审核结果已正式发布。')
    await load()
  } catch (error: any) {
    if (error !== 'cancel' && error !== 'close') ElMessage.error(apiErrorMessage(error))
  }
}

watch([keyword, conclusionFilter], () => {
  resultPage.value = 1
  if (filterTimer) clearTimeout(filterTimer)
  filterTimer = setTimeout(() => loadBatch(), 300)
})

onUnmounted(() => {
  if (filterTimer) clearTimeout(filterTimer)
  resultRequestId.value++
})

onMounted(load)
</script>

<template>
  <div class="page-stack graduation-page">
    <section class="page-intro">
      <div>
        <span class="section-kicker">DEGREE CLEARANCE</span>
        <h2>{{ isStudent ? '我的毕业资格' : '毕业资格审核' }}</h2>
        <p>{{ isStudent ? '查看学校正式发布的毕业资格审核结论和未完成项目。' : '以培养方案和已发布成绩为依据批量计算，支持人工复核并形成不可变发布结果。' }}</p>
      </div>
      <el-button v-if="isPublisher && !isStudent" type="primary" :icon="Plus" @click="createDialog = true">新建审核批次</el-button>
      <el-button v-else :icon="Refresh" @click="load">刷新</el-button>
    </section>

    <template v-if="isStudent">
      <section v-if="myResult" class="graduation-certificate" v-loading="loading">
        <header>
          <span>OFFICIAL DEGREE CLEARANCE</span>
          <i>{{ myResult.graduationYear }}</i>
        </header>
        <div class="certificate-person">
          <div><span>学生姓名</span><b>{{ myResult.name }}</b></div>
          <div><span>学号</span><b>{{ myResult.studentNumber }}</b></div>
          <div><span>专业</span><b>{{ myResult.majorName }}</b></div>
        </div>
        <div class="certificate-conclusion" :class="{ eligible: myResult.conclusion === 'Eligible' }">
          <el-icon><DocumentChecked /></el-icon>
          <div><span>毕业资格审核结论</span><h3>{{ conclusionLabels[myResult.conclusion] }}</h3><p>{{ myResult.batchName }} · 发布于 {{ dateText(myResult.publishedAt) }}</p></div>
        </div>
        <div class="certificate-metrics">
          <div><span>学分完成</span><b>{{ myResult.earnedCredits }} / {{ myResult.requiredCredits }}</b><el-progress :percentage="percent(myResult.earnedCredits, myResult.requiredCredits)" :show-text="false" /></div>
          <div><span>必修要求</span><b>{{ myResult.passedRequiredCourseCount }} / {{ myResult.requiredCourseCount }}</b><p>已完成 / 应完成</p></div>
          <div><span>未解决不及格</span><b>{{ myResult.failedCourseCount }}</b><p>门课程</p></div>
        </div>
        <footer>
          <div><span>未完成课程</span><b>{{ myResult.missingCourseNames || '无' }}</b></div>
          <div v-if="myResult.reviewComment"><span>复核意见</span><b>{{ myResult.reviewComment }}</b></div>
        </footer>
      </section>
      <el-empty v-else v-loading="loading" description="学校尚未发布你的毕业资格审核结果" />
    </template>

    <template v-else>
      <section class="graduation-batch-strip">
        <button v-for="batch in batches" :key="batch.id" :class="{ active: selected?.id === batch.id }" @click="selectBatch(batch.id)">
          <span>{{ batch.graduationYear }}届 · {{ batch.enrollmentYear }}级</span>
          <b>{{ batch.name }}</b>
          <small>{{ batch.resultCount }} 人 · {{ batch.eligibleCount }} 人符合</small>
          <i>{{ statusLabels[batch.status] }}</i>
        </button>
      </section>

      <section v-if="selected" class="graduation-workbench" v-loading="loading">
        <header>
          <div><span>AUDIT REGISTER</span><h3>{{ selected.name }}</h3><p>计算时间 {{ dateText(selected.calculatedAt) }} · 规则基于已发布培养方案与成绩</p></div>
          <div v-if="selected.status === 'Draft' && isPublisher">
            <el-button :icon="Refresh" @click="calculate">重新计算</el-button>
            <el-button type="primary" :icon="Stamp" @click="publish">发布结果</el-button>
          </div>
          <el-tag v-else type="success" effect="plain">结果已锁定</el-tag>
        </header>

        <div class="graduation-summary">
          <div><span>参审学生</span><b>{{ selected.resultCount }}</b><small>人</small></div>
          <div><span>符合条件</span><b>{{ selected.eligibleCount }}</b><small>人</small></div>
          <div><span>暂不符合</span><b>{{ selected.ineligibleCount }}</b><small>人</small></div>
          <div><span>人工调整</span><b>{{ selected.overrideCount }}</b><small>人</small></div>
        </div>

        <div class="graduation-filter">
          <el-input v-model="keyword" clearable placeholder="搜索学号、姓名、专业或班级" />
          <el-select v-model="conclusionFilter" clearable placeholder="全部结论">
            <el-option label="符合毕业条件" value="Eligible" />
            <el-option label="暂不符合" value="Ineligible" />
          </el-select>
          <span>共 {{ resultTotal }} 条</span>
        </div>

        <div class="graduation-result-list">
          <article v-for="row in resultItems" :key="row.id">
            <div class="graduation-student"><span>{{ row.studentNumber }} · {{ row.className }}</span><h4>{{ row.name }}</h4><p>{{ row.majorName }} · {{ row.planName || '未匹配培养方案' }}</p></div>
            <div class="credit-progress"><span>学分完成度</span><b>{{ row.earnedCredits }} / {{ row.requiredCredits }}</b><el-progress :percentage="percent(row.earnedCredits, row.requiredCredits)" :show-text="false" /></div>
            <div class="course-clearance"><span>必修要求</span><b>{{ row.passedRequiredCourseCount }} / {{ row.requiredCourseCount }}</b><small v-if="row.missingCourseNames">缺：{{ row.missingCourseNames }}</small><small v-else>指定必修与课程组均已完成</small></div>
            <div class="graduation-conclusion" :class="{ eligible: row.conclusion === 'Eligible' }"><el-icon><Check /></el-icon><span>{{ conclusionLabels[row.conclusion] }}</span><small v-if="row.isOverridden">人工复核</small><small v-else>规则计算</small></div>
            <el-button v-if="selected.status === 'Draft'" link type="primary" @click="openDecision(row)">人工复核</el-button>
          </article>
          <el-empty v-if="!resultItems.length" description="没有符合筛选条件的审核结果" />
          <el-pagination
            v-if="resultTotal > resultPageSize"
            v-model:current-page="resultPage"
            :page-size="resultPageSize"
            :total="resultTotal"
            layout="total, prev, pager, next"
            @current-change="loadBatch()"
          />
        </div>
      </section>
      <el-empty v-else v-loading="loading" description="尚未建立毕业资格审核批次" />
    </template>

    <el-dialog v-model="createDialog" title="新建毕业资格审核批次" width="620px">
      <el-form label-position="top">
        <el-form-item label="批次名称"><el-input v-model="batchForm.name" /></el-form-item>
        <div class="form-grid">
          <el-form-item label="毕业年份"><el-input-number v-model="batchForm.graduationYear" :min="2000" :max="2200" /></el-form-item>
          <el-form-item label="目标入学年级"><el-input-number v-model="batchForm.enrollmentYear" :min="2000" :max="2200" /></el-form-item>
        </div>
        <el-form-item label="说明"><el-input v-model="batchForm.notes" type="textarea" :rows="3" /></el-form-item>
      </el-form>
      <template #footer><el-button @click="createDialog = false">取消</el-button><el-button type="primary" @click="createBatch">建立并计算</el-button></template>
    </el-dialog>

    <el-dialog v-model="decisionDialog" title="人工复核毕业资格" width="620px">
      <div v-if="decisionTarget" class="review-target">
        <span>{{ decisionTarget.studentNumber }}</span><b>{{ decisionTarget.name }} · {{ decisionTarget.majorName }}</b>
        <p>规则结论：{{ conclusionLabels[decisionTarget.calculatedConclusion] }} · 学分 {{ decisionTarget.earnedCredits }} / {{ decisionTarget.requiredCredits }}</p>
      </div>
      <el-form label-position="top">
        <el-form-item label="复核结论">
          <el-radio-group v-model="decisionForm.conclusion">
            <el-radio-button value="Eligible">符合毕业条件</el-radio-button>
            <el-radio-button value="Ineligible">暂不符合</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="复核意见"><el-input v-model="decisionForm.comment" type="textarea" :rows="4" maxlength="500" show-word-limit /></el-form-item>
      </el-form>
      <template #footer><el-button @click="decisionDialog = false">取消</el-button><el-button type="primary" @click="saveDecision">保存复核结论</el-button></template>
    </el-dialog>
  </div>
</template>
