<script setup>
import {ref, watch} from "vue";
import {useQuasar} from "quasar";
import courseScheduleApi from "app/src/api/course/course_schedule";
import {useRoute, useRouter} from "vue-router";
import AdminClassAddPane from "pages/admin/schedule/AdminCourseScheduleAddPane.vue";
import AdminClassEditPane from "pages/admin/schedule/AdminCourseScheduleEditPane.vue";
import AdminClassDuplicatePane from "pages/admin/schedule/AdminCourseScheduleClonePane.vue";
import courseApi from "app/src/api/course/course";
import dayjs from "dayjs";
import termUtils from "app/src/utils/term";

const classListColumns = [
  // {name: 'course', align: 'left', label: '课程', sortable: true},
  {name: 'term', align: 'left', label: '学期', field: 'term', sortable: true},
  {name: 'section', align: 'left', label: '节次', field: 'section', sortable: true},
  {name: 'weekday', align: 'left', label: '星期', field: 'weekday', sortable: true},
  {name: 'week', align: 'left', label: '周次', field: 'week', sortable: true},
  {name: 'place', align: 'left', label: '地点', field: 'place', sortable: true},
  // {name: 'teachers', align: 'left', label: '教师', field: 'teachers', sortable: true},
  {name: 'edit', align: 'left', label: '操作', field: 'edit'}
]

const courseScheduleRows = ref([])

const classListPagination = ref({
  sortBy: 'term',
  descending: true,
  page: 1,
  rowsPerPage: 10,
  rowsNumber: 10
})

const route = useRoute()

const courseId = route.params.id

const filter = ref('')

const loading = ref(true)

const quasar = useQuasar()

const course = ref({
  "id": "",
  "name": "",
  "courseHours": 0,
  "targetMajor": [],
  "targetGrade": [],
  "springTerm": false
})

async function init() {
  if (courseId !== undefined && courseId !== '') {
    try {
      course.value = await courseApi.getInfo(courseId)

      // 先拿第一页的数据
      try {
        const response = await courseScheduleApi.list(courseId, undefined, 1, 10)
        updateListData(response)
      } catch (e) {
        quasar.dialog({
          transitionShow: 'fade',
          transitionHide: 'fade',
          title: '啊哈？',
          message: e.message
        })
      } finally {
        loading.value = false
      }
    } catch (e) {
      quasar.dialog({
        transitionShow: 'fade',
        transitionHide: 'fade',
        title: '啊哈？',
        message: e.message
      })
    } finally {
      loading.value = false
    }
  }
}

init()

function forceRefreshSchedule() {
  courseScheduleRows.value = []
  classListPagination.value.page = 1
  classListPagination.value.rowsPerPage = 10
  refreshClasses({pagination: {page: 1, rowsPerPage: 10}})
}

async function refreshClasses(props) {
  const {page, rowsPerPage} = props.pagination

  loading.value = true;

  try {
    const response = await courseScheduleApi.list(courseId, filterTerm.value, page, rowsPerPage === 0 ? 999 : rowsPerPage);
    updateListData(response);
  } catch (e) {
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    });
  } finally {
    loading.value = false;
  }
}

function updateListData(response) {
  classListPagination.value.page = response.current
  classListPagination.value.rowsNumber = response.total
  classListPagination.value.rowsPerPage = response.pageSize

  let tmp = []
  response.result.forEach(result => {
    tmp.push({
      id: result.id,
      name: result.name,
      course: result.course,
      startWeek: result.startWeek,
      endWeek: result.endWeek,
      term: result.academicTerm,
      section: result.time,
      weekday: result.weekday,
      place: result.place,
      ratio: result.ratio
    })
  })

  courseScheduleRows.value.splice(0, courseScheduleRows.value.length, ...tmp)
}

const classAddDialogState = ref(false)

function openCourseScheduleAddDialog() {
  classAddDialogState.value = !classAddDialogState.value
}

/**
 *
 * @type {import('vue').Ref<{
 *    id: number,
 *    course: number,
 *    startWeek: number,
 *    endWeek: number,
 *    weekday: number,
 *    term: string,
 *    section: number,
 *    place: string
 * }>}
 */
const courseScheduleInfoForm = ref({
  id: 0,
  course: 0,
  startWeek: 1,
  endWeek: 17,
  section: 1,
  weekday: 1,
  term: "2023-2024-2",
  place: "黄家湖"
})

const courseScheduleEditDialogState = ref(false)

async function openCourseScheduleEditDialog(scheduleId) {
  if (courseScheduleEditDialogState.value === false) {
    loading.value = true

    try {
      const data = await courseScheduleApi.getInfo(scheduleId)
      courseScheduleInfoForm.value.id = scheduleId
      courseScheduleInfoForm.value.course = data.course
      courseScheduleInfoForm.value.startWeek = data.startWeek
      courseScheduleInfoForm.value.endWeek = data.endWeek
      courseScheduleInfoForm.value.term = data.academicTerm
      courseScheduleInfoForm.value.section = data.time
      courseScheduleInfoForm.value.weekday = data.weekday
      courseScheduleInfoForm.value.place = data.place

      courseScheduleEditDialogState.value = true

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

    loading.value = false
  }
}

async function doDeleteClass(id) {
  const dialog = quasar.dialog({
    transitionShow: 'fade',
    transitionHide: 'fade',
    message: '与服务器通信中...',
    progress: true,
    persistent: true,
    ok: false
  })

  try {
    await courseScheduleApi.deleteCourseSchedule(id)
    dialog.hide()
    forceRefreshSchedule()
  } catch (e) {
    dialog.update({
      title: '啊哈？',
      message: e.message,
      progress: false,
      ok: true
    })
  }
}

function deleteClassAction(id, name) {
  const dialog = quasar.dialog({
    transitionShow: 'fade',
    transitionHide: 'fade',
    title: '确认？',
    message: '真的要删除"' + name + '"？',
    cancel: true,
  })
    .onCancel(() => dialog.hide())
    .onOk(() => doDeleteClass(id))
}

const courseScheduleClonePaneState = ref(false)

function openCourseScheduleCloneDialog() {
  courseScheduleClonePaneState.value = true
}

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

const filterTerm = ref('全部')

const terms = []

function generateTerm() {
  terms.push('全部')
  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`)
  }
}

generateTerm()

watch(filterTerm, forceRefreshSchedule)

</script>

<template>
  <div class="flex flex-col gap-4 px-6 pt-1 pb-6">
    <div>
      <h1 class="text-3xl mb-1">管理课程『{{ course.name }}』的上课安排</h1>
      <p>在这里可以添加/删除课程的课堂安排信息</p>
    </div>

    <div v-if="courseId !== undefined && courseId !== ''" class="flex flex-col gap-1 max-w-full">
      <q-table :filter="filter" :columns="classListColumns" :rows="courseScheduleRows" table-class="table-auto"
               v-model:pagination="classListPagination" :loading="loading" @request="refreshClasses"
               class="table-admin max-w-full">
        <template v-slot:top>
          <div class="flex flex-row gap-4 justify-between w-full">
            <div class="flex flex-row gap-2">
              <q-btn unelevated @click="openCourseScheduleAddDialog" color="primary" icon="add" label="添加课程安排"/>
              <q-btn unelevated @click="openCourseScheduleCloneDialog" color="primary" icon="content_copy"
                     label="复制其他学年课程安排"/>
              <q-btn unelevated @click="forceRefreshSchedule" color="primary" icon="refresh" label="刷新"/>
              <q-select :options="terms" v-model="filterTerm" class="w-64" outlined label="学期"></q-select>
            </div>
          </div>
        </template>
        <template v-slot:body="props">
          <q-tr :props="props">
            <q-td key="term" :props="props">{{ props.row.term }}</q-td>
            <q-td key="section" :props="props">
              第{{ props.row.section + 1 }}大节
            </q-td>
            <q-td key="weekday" :props="props">
              星期{{ numbers[props.row.weekday] }}
            </q-td>
            <q-td key="week" :props="props">
              {{ props.row.startWeek }}-{{ props.row.endWeek }}
            </q-td>
            <q-td key="place" :props="props">{{ props.row.place }}</q-td>
            <q-td key="edit" :props="props">
              <div class="flex flex-row justify-start gap-4 w-full transition-all">
                <q-btn @click="openCourseScheduleEditDialog(props.row.id)" outline label="查看/修改" icon="edit"/>
                <q-btn @click="deleteClassAction(props.row.id, props.row.name)" outline color="red" label="删除"
                       icon="delete"/>
              </div>
            </q-td>
          </q-tr>
        </template>
      </q-table>

      <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"
      />

      <AdminClassAddPane v-model:open="classAddDialogState" :course-id="courseId" @on-ok="forceRefreshSchedule()"/>

      <AdminClassEditPane v-model:data="courseScheduleInfoForm" v-model:open="courseScheduleEditDialogState"
                          :course-id="courseId"
                          @on-close="openCourseScheduleEditDialog" @on-ok="forceRefreshSchedule()"/>

      <AdminClassDuplicatePane v-model:open="courseScheduleClonePaneState" :course-id="courseId"
                               @on-ok="forceRefreshSchedule()"/>
    </div>

    <div v-else class="flex flex-col gap-2 pt-4 max-w-full">
      <span class="text-base">请前往课程列表选择课程后再进行课堂管理</span>
      <router-link to="/admin/course">
        <q-btn class="text-base" color="primary" outline label="好好好，走吧"></q-btn>
      </router-link>
    </div>
  </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>
