<script setup>
import {ref, watch} from "vue";
import {useRoute} from "vue-router";
import {useQuasar} from "quasar";
import scoreApi from "app/src/api/score/score";
import TeacherScoreImportPane from "pages/teacher/score/TeacherScoreImportPane.vue";
import courseApi from "app/src/api/course/course";
import dayjs from "dayjs";
import termUtils from "app/src/utils/term";

const route = useRoute()

const quasar = useQuasar()

const loading = ref(false)

const columns = [
  {name: 'studentName', label: '学生', align: 'left', sortable: true},
  {name: 'studentNumber', label: '学号', align: 'left', sortable: true},
  {name: 'usualScore', label: '平时分', align: 'left', sortable: true},
  {name: 'examScore', label: '考试分', align: 'left', sortable: true},
  {name: 'examRatio', label: '考试占比', align: 'left'},
  {name: 'final', label: '最终成绩', align: 'left', sortable: true},
  {name: 'operation', label: '操作', align: 'center', sortable: true}
]

const term = ref('')
const terms = []

function generateTerm() {
  const now = dayjs()
  const thisYear = now.year()
  for (let i = -3; i < 4; i++) {
    const year = thisYear + i
    terms.push(`${year}-${year + 1}-1`)
    terms.push(`${year}-${year + 1}-2`)
  }

  term.value = termUtils.getCurrentTermString()
}

generateTerm()

watch(term, async () => {
  loading.value = true
  await loadScore()
  loading.value = false
})

const scoreRows = ref([])

const scheduleId = route.params.id

const courseInfo = ref({
  id: "",
  name: "",
  course: "",
  startWeek: 1,
  endWeek: 1,
  time: 1,
  weekday: 1,
  academicTerm: "",
  place: "",
  ratio: 1
})

async function loadScheduleInfo() {
  if (!scheduleId) {
    return;
  }

  loading.value = true;

  try {
    courseInfo.value = await courseApi.getInfo(scheduleId)
    await loadScore()
  } catch (e) {
    console.warn(e);
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    });
  }

  loading.value = false;
}

loadScheduleInfo()

async function loadScore() {
  loading.value = true
  scoreRows.value = []

  const scores = await scoreApi.teacher.getScheduleStudentScore(scheduleId, term.value)
  for (const score of scores) {
    if (!score.examRatio) {
      score.examRatio = courseInfo.value.examRatio
    }

    scoreRows.value.push(score)
  }

  loading.value = false
}

const editSwitch = ref({})

function setEditStatus(number, status) {
  editSwitch.value[number] = status
}

function getEditStatus(number) {
  return editSwitch.value[number] !== undefined && editSwitch.value[number] !== false
}

function getFinalScore(usual, exam, ratio) {
  let weightedUsual = usual * (1 - ratio)
  let weightedExam = exam * ratio

  return (weightedUsual + weightedExam).toFixed(2)
}

function exportAction() {
  quasar.dialog({
    transitionShow: 'fade',
    transitionHide: 'fade',
    title: '导出成绩表',
    message: `
      点击确认生成并下载『${courseInfo.value.name}』的全部学生成绩信息<br>
      成绩统计信息只统计已经记录的成绩信息，未记录的成绩信息则留空`,
    html: true,
    cancel: true,
  })
    .onOk(exportExcel)
}

async function exportExcel() {
  try {
    loading.value = true;
    const response = await scoreApi.exportScoreExcel(courseInfo.value.id, term.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;
}

const scoreImportPaneState = ref(false)

function openScoreImportPane() {
  scoreImportPaneState.value = true
}

async function updateScoreForSingleStudent(scoreInfo) {
  if (scoreInfo.usualScore === undefined || scoreInfo.examScore === undefined ||
    scoreInfo.usualScore === '' || scoreInfo.examScore === '') {

    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: '成绩信息不完整'
    });

    return;
  }

  try {
    loading.value = true;
    await scoreApi.teacher.updateScore(courseInfo.value.id, term.value, scoreInfo);
  } catch (e) {
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    });

    try {
      await loadScore();
    } catch (e) {
      quasar.dialog({
        transitionShow: 'fade',
        transitionHide: 'fade',
        title: '啊哈？',
        message: e.message
      });
    }
  }

  loading.value = false;
}

const filter = ref('')

</script>

<template>

  <div class="flex flex-col gap-8 px-6 pt-1 pb-6">
    <div>
      <h1 class="text-3xl mb-1">成绩信息 - {{ courseInfo.name }}</h1>
    </div>

    <div v-if="scheduleId !== undefined && scheduleId !== ''"
         class="flex flex-col gap-4 justify-start content-start max-w-full">
      <q-table flat :filter="filter" :columns="columns" :rows="scoreRows" :loading="loading"
               class="table-teacher w-full max-h-full max-w-full">
        <template v-slot:top>
          <!--          <q-btn class="q-ml-sm" color="primary" label="保存" icon="save"/>-->
          <div class="flex flex-row gap-2 justify-between flex-grow">
            <div class="flex flex-row gap-2">
              <q-btn class="q-ml-sm" color="primary" @click="exportAction" icon="upload" label="导出Excel成绩"/>
              <q-btn class="q-ml-sm" color="primary" @click="openScoreImportPane" icon="download"
                     label="从Excel导入成绩"/>
              <q-space/>
              <q-select class="text-base flex-grow w-64" outlined v-model="term" :options="terms" label="学期"/>
            </div>

            <q-input outlined color="primary" v-model="filter" placeholder="搜索任意字段">
              <template v-slot:append>
                <q-icon name="search"/>
              </template>
            </q-input>
          </div>
        </template>
        <template v-slot:body="props">
          <q-tr :props="props">
            <q-td key="studentName" :props="props">
              <span class="break-all whitespace-normal">{{ props.row.studentName }}</span>
            </q-td>
            <q-td key="studentNumber" :props="props">{{ props.row.studentNumber }}</q-td>
            <q-td key="usualScore" :props="props">
              <q-input v-if="getEditStatus(props.row.number)" v-model="props.row.usualScore"
                       :disable="!getEditStatus(props.row.number)" type="number" dense/>
              <div v-else class="w-full">{{ props.row.usualScore }}</div>
            </q-td>
            <q-td key="examScore" :props="props">
              <q-input v-if="getEditStatus(props.row.number)" v-model="props.row.examScore"
                       :disable="!getEditStatus(props.row.number)" type="number" dense/>
              <div v-else class="w-full">{{ props.row.examScore }}</div>
            </q-td>
            <q-td key="examRatio" :props="props">
              <q-input v-if="getEditStatus(props.row.number)" v-model="props.row.examRatio"
                       :placeholder="props.row.examRatio"
                       :disable="!getEditStatus(props.row.number)" type="number" dense/>
              <div v-else class="w-full">{{ props.row.examRatio }}</div>
            </q-td>
            <q-td key="final" :props="props">
              {{ getFinalScore(props.row.usualScore, props.row.examScore, props.row.examRatio) }}
            </q-td>
            <q-td key="operation" :props="props">
              <div class="flex flex-row justify-center gap-4 w-full transition-all">
                <q-btn v-if="!getEditStatus(props.row.number)"
                       @click="setEditStatus(props.row.number, true)"
                       outline color="primary" label="编辑" icon="edit"/>
                <q-btn v-if="getEditStatus(props.row.number)"
                       @click="setEditStatus(props.row.number, false)"
                       outline color="red" label="取消" icon="close"/>
                <q-btn v-if="getEditStatus(props.row.number)"
                       @click="setEditStatus(props.row.number, false);updateScoreForSingleStudent(props.row)"
                       outline color="blue" label="确认" icon="check"/>
              </div>
            </q-td>
          </q-tr>
        </template>
      </q-table>

      <q-separator/>

      <router-link to="/teacher/score">
        <q-btn class="text-base w-full" align="left" color="primary" flat icon="arrow_back"
               label="返回课堂列表"></q-btn>
      </router-link>
    </div>
    <div v-else class="flex flex-col gap-4 text-base">
      <q-separator/>
      <p>啊哈？</p>
      <p>你不应该看见这些字，我猜你应该是误打误撞进来的吧？</p>
      <div class="flex flex-row gap-4">
        <router-link to="/teacher/score">
          <q-btn class="text-base w-full" align="left" color="primary" flat icon="arrow_forward"
                 label="没事，这就回去"></q-btn>
        </router-link>
      </div>
    </div>

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

    <TeacherScoreImportPane v-model:open="scoreImportPaneState" v-model:score-list="scoreRows"
                            v-model:course-info="courseInfo" v-model:term="term" @on-close="loadScore"/>
  </div>
</template>

<style scoped lang="sass">
.score-dialog-body
  max-width: 85vw
  max-height: 95vh

@media not all and (min-width: 400px)
  .score-table
    th, td
      font-size: unset !important
</style>
