<script setup>

import {ref, watch} from "vue";
import {exportFile, useQuasar} from "quasar";
import dayjs from "dayjs";
import majorManager from "app/src/api/major/major";
import {useRoute} from "vue-router";
import courseSelectionApi from "app/src/api/course/course_selection";
import termUtils from "app/src/utils/term";
import scoreApi from "app/src/api/score/score";
import courseApi from "app/src/api/course/course";
import {useMajorsStore} from "stores/majors";

const studentListPagination = ref({
  sortBy: 'studentNumber',
  descending: false,
  page: 1,
  rowsPerPage: 50,
  rowsNumber: 10
})

const selectedStudentListColumns = [
  {name: 'name', align: 'left', label: '学生', sortable: true},
  {name: 'studentNumber', align: 'left', label: '学号', field: 'studentNumber', sortable: true},
  {name: 'grade', align: 'left', label: '年级', field: 'grade', sortable: true},
  {name: 'major', align: 'left', label: '专业', field: 'major', sortable: true},
  {name: 'clazz', align: 'left', label: '班级', field: 'clazz', sortable: true},
  {name: 'schedule', align: 'left', label: '选择时间', field: 'schedule'},
]

const notSelectStudentListColumns = [
  {name: 'name', align: 'left', label: '学生', sortable: true},
  {name: 'studentNumber', align: 'left', label: '学号', field: 'studentNumber', sortable: true},
  {name: 'grade', align: 'left', label: '年级', field: 'grade', sortable: true},
  {name: 'major', align: 'left', label: '专业', field: 'major', sortable: true},
  {name: 'clazz', align: 'left', label: '班级', field: 'clazz', sortable: true},
]

/**
 *
 * @type {import('vue').Ref<any>}
 */
const columnsRef = ref(selectedStudentListColumns)

const viewTypeRef = ref('selected')

watch(viewTypeRef, (value) => {
  switch (value) {
    case 'selected':
      columnsRef.value = selectedStudentListColumns
      break;
    default:
      columnsRef.value = notSelectStudentListColumns
  }

  loadStudents()
})

const studentRows = ref([])

const loading = ref(true)

const quasar = useQuasar()

const route = useRoute()

const courseId = route.params.id

const filterTerm = ref('2023-2024-2')

const terms = []

function generateTerm() {
  const now = dayjs().subtract(6, 'year')
  const thisYear = now.year()
  for (let i = -1; i < 10; i++) {
    const year = thisYear + i
    terms.push(`${year}-${year + 1}-1`)
    terms.push(`${year}-${year + 1}-2`)
  }

  filterTerm.value = termUtils.getCurrentTermString()
}

generateTerm()

watch(filterTerm, loadStudents)

async function init() {
  loading.value = true

  try {
    const courseSelectionInfoList = await courseSelectionApi.list(Number(courseId), filterTerm.value)
    processCourseSelectionViewData(courseSelectionInfoList)
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  }

  loading.value = false
}

init()

async function loadStudents() {
  loading.value = true

  try {
    let info
    switch (viewTypeRef.value) {
      case 'selected':
        info = await courseSelectionApi.list(Number(courseId), filterTerm.value);
        break
      default:
        info = await courseSelectionApi.listNotSelected(Number(courseId), filterTerm.value);
    }

    processCourseSelectionViewData(info)
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  }

  loading.value = false
}

const sectionDesc = {
  0: '第一大节(1~2)',
  1: '第二大节(3~4)',
  2: '第三大节(5~6)',
  3: '第四大节(7~7)',
  4: '第五大节(9~10)',
  5: '第六大节(11~12)',
}

const weekdayDesc = {
  1: '星期一',
  2: '星期二',
  3: '星期三',
  4: '星期四',
  5: '星期五',
  6: '星期六',
  7: '星期日',
}

/**
 *
 * @param courseSelectionInfoList {[]}
 */
function processCourseSelectionViewData(courseSelectionInfoList) {
  if (courseSelectionInfoList) {
    studentListPagination.value.page = 1
    studentListPagination.value.rowsNumber = courseSelectionInfoList.length

    const studentSelectionMap = {}
    courseSelectionInfoList.forEach(info => {
      const studentSelectionInfo = studentSelectionMap[info.uid]
      if (studentSelectionInfo) {
        studentSelectionMap[info.uid].schedule +=
          `，\n${weekdayDesc[info.weekday]}${sectionDesc[info.time]}(${info.startWeek}周~${info.endWeek}周)`
      } else {
        studentSelectionMap[info.uid] = {
          name: info.name,
          studentNumber: info.studentNumber,
          grade: info.grade,
          major: info.major,
          clazz: info.clazz,
          schedule:
            `${weekdayDesc[info.weekday]}${sectionDesc[info.time]}(${info.startWeek}周~${info.endWeek}周)`,
        }
      }
    })

    studentRows.value.splice(0, studentRows.value.length)
    for (const uid in studentSelectionMap) {
      studentRows.value.push(studentSelectionMap[uid])
    }
  }
}

async function exportNameListExcel() {
  loading.value = true;
  try {
    await courseSelectionApi.exportStudentExcel(courseId, filterTerm.value)
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  }
  loading.value = false;
}

async function exportNotSelectStudentExcel() {
  loading.value = true;
  try {
    await courseSelectionApi.exportNotSelectStudentExcel(courseId, filterTerm.value)
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  }
  loading.value = false;
}

async function exportScoreExcel() {
  loading.value = true;

  try {
    const response = await scoreApi.exportScoreExcel(courseId, filterTerm.value);
    if (!response) {
      quasar.dialog({
        transitionShow: 'fade',
        transitionHide: 'fade',
        title: '啊哈？',
        message: response
      });
    }
  } catch (e) {
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    });
  }

  loading.value = false;
}

function exportStudentNameList() {
  switch (viewTypeRef.value) {
    case 'selected':
      exportNameListExcel();
      break;
    default:
      exportNotSelectStudentExcel()
  }
}

const majorStore = useMajorsStore();

</script>

<template>
  <div class="flex flex-col gap-4 px-6 pt-1 pb-6">
    <div>
      <h1 class="text-3xl mb-1">课程选课情况</h1>
      <p>在这里可以查看该课程的学生选课情况</p>
    </div>

    <div class="flex flex-col gap-1 max-w-full">
      <q-table v-model:pagination="studentListPagination" :loading="loading"
               :columns="columnsRef" :rows="studentRows" class="table-admin max-w-full"
               :pagination="studentListPagination">
        <template v-slot:top>
          <div class="flex flex-row gap-2 flex-grow justify-between">
            <div class="flex flex-row gap-4">
              <q-select :options="terms" v-model="filterTerm" class="w-64" outlined label="学期"></q-select>
              <div class="flex flex-col gap-2">
                <span><b>查看类型</b></span>
                <div class="flex flex-row gap-2">
                  <q-radio dense v-model="viewTypeRef" val="selected" label="已选学生"/>
                  <q-radio dense v-model="viewTypeRef" val="not-select" label="应选未选学生"/>
                </div>
              </div>
            </div>

            <div class="flex flex-row gap-2">
              <q-btn @click="exportScoreExcel()" unelevated color="primary" icon="upload" label="导出成绩Excel"/>
              <q-btn label="导出名单Excel" unelevated color="indigo" icon="upload" @click="exportStudentNameList()"/>
            </div>
          </div>
        </template>
        <template v-slot:body="props">
          <q-tr :props="props">
            <q-td key="name" :props="props">
              <span class="break-all whitespace-normal">{{ props.row.name }}</span>
            </q-td>
            <q-td key="studentNumber" :props="props">{{ props.row.studentNumber }}</q-td>
            <q-td key="grade" :props="props">{{ props.row.grade }}</q-td>
            <q-td key="major" :props="props">{{ majorStore.majorNames[props.row.major] }}</q-td>
            <q-td key="clazz" :props="props">{{ props.row.clazz }}</q-td>
            <q-td key="schedule" :props="props">{{ props.row.schedule }}</q-td>
          </q-tr>
        </template>
      </q-table>
    </div>

    <div>
      <router-link to="/admin/course">
        <q-btn class="text-base w-fit mt-4" color="primary" outline label="返回课程列表"></q-btn>
      </router-link>
    </div>

    <q-inner-loading
      :showing="loading"
      label="与服务器通信中..."
      label-class="text-teal"
      label-style="font-size: 1.1em"
      color="gray"
      class="z-10"
    />
  </div>
</template>

<style lang="sass">
.table-admin
  transition: all 0.2s linear 0.2s

  th, td
    font-size: 1rem !important

  th
    font-weight: bold

  .q-table__top,
  .q-table__bottom,
  thead tr:first-child th
    background-color: white

  thead tr:first-child th:first-child
    background-color: white

  tbody tr:nth-child(odd)
    background-color: rgb(248, 248, 248)

  tbody tr:nth-child(even)
    background-color: white

  th:first-child,
  td:first-child
    position: sticky
    left: 0
    z-index: 1

  th:first-child
    z-index: 3 !important

  thead tr th
    position: sticky
    z-index: 2

  thead tr:first-child th
    top: 0
</style>

<style scoped lang="sass">

</style>

