<script setup>
import {QCalendarScheduler} from '@quasar/quasar-ui-qcalendar/src/QCalendarScheduler'
import '@quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass'
import '@quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass'
import '@quasar/quasar-ui-qcalendar/src/QCalendarScheduler.sass'
import {ref} from "vue";
import dayjs from "dayjs";
import {useQuasar} from "quasar";
const quasar = useQuasar()

/**
 * @typedef {Object} CourseSchedule
 * @property {number} courseId - The ID of the course.
 * @property {number} scheduleId - The ID of the schedule.
 * @property {string} courseName - The name of the course.
 * @property {number} courseHours - The number of hours for the course.
 * @property {number} startWeek - The starting week of the course.
 * @property {number} endWeek - The ending week of the course.
 * @property {number} time - The time of the course.
 * @property {number} weekday - The day of the week for the course.
 * @property {string} academicTerm - The academic term of the course.
 * @property {boolean} springTerm - Whether the course is in the spring term.
 * @property {string} place - The place of the course.
 * @property {number} examRatio - The ratio of the exam.
 * @property {string} createTime - The creation time of the course.
 */

const cellHeight = 120

const toDay = dayjs()
const displayDate = toDay.format("YYYY-MM-DD")

const resources = [
  {id: 0, name: '1~2'},
  {id: 1, name: '3~4'},
  {id: 2, name: '5~6'},
  {id: 3, name: '7~8'},
  {id: 4, name: '9~10'},
  {id: 5, name: '11~12'},
]

// key为节次（大节），value为一行内的所有课
const displayCourses = {
  0: [],
  1: [],
  2: [],
  3: [],
  4: [],
  5: [],
}

const fullCourseList = ref([])

function clear() {
  for (let i = 0; i < 6; i++) {
    displayCourses[i] = []
  }
}

function filterCourses(week) {
  clear()

  if (week) {
    fullCourseList.value.forEach(course => {
      if (course.startWeek <= week && course.endWeek >= week) {
        if (!displayCourses[course.time]) {
          displayCourses[course.time] = []
        }

        displayCourses[course.time].push(course)
      }
    })
  } else {
    fullCourseList.value.forEach(course => {
      if (!displayCourses[course.time]) {
        displayCourses[course.time] = []
      }

      displayCourses[course.time].push(course)
    })
  }

  refreshView()
}

function addCourse(course) {
  if (displayCourses[course.time] === undefined) {
    displayCourses[course.time] = []
  }

  fullCourseList.value.push(course)
  displayCourses[course.time].push(course)
}

const refreshFlag = ref(false)

function refreshView() {
  refreshFlag.value = !refreshFlag.value
}

const gird = {
  '0': [],
  '1': [],
  '2': [],
  '3': [],
  '4': [],
  '5': [],
}

const courses = ref([])

function getGirdScheduleObject(scope) {
  const result = []
  const section = scope.resourceIndex

  const coursesInSection = displayCourses[section]
  for (let i = 0; coursesInSection !== undefined && i < coursesInSection.length; i++) {
    for (let j = 0; j < coursesInSection.length; j++) {
      const course = coursesInSection[j]
      let mark = gird[section][course.weekday]
      if (!mark) {
        gird[section][course.weekday] = {}
      }

      gird[section][course.weekday][course.name] = course

      result.push({
        official: course.official,
        info: course,
        left: getLeft(scope, course),
        width: getWidth(scope),
        title: course.name,
        mark: gird[section][course.weekday]
      })
    }
  }

  return result
}

function getStyle(event) {
  return {
    background: event.official ? 'rgb(0,157,255)' : 'green',
    position: 'absolute',
    left: event.left,
    width: event.width,
    height: cellHeight + 'px',
    'z-index': event.official ? 1 : 10,
  }
}

function getLeft(scope, course) {
  const left = (course.weekday - 1) * parseFloat(scope.cellWidth)
  return left + (scope.cellWidth.endsWith('%') ? '%' : 'px')
}

function getWidth(scope) {
  const cellWidth = parseFloat(scope.cellWidth)
  return cellWidth + 'px'
}

const qcalendarView = ref()

const loading = ref(false)

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

const currentSchedule = ref({})
const detailDialogOpenState = ref(false)

/**
 *
 * @param schedule {CourseSchedule}
 */
function showDetail(schedule) {
  currentSchedule.value = schedule
  detailDialogOpenState.value = true
}

defineExpose({
  addCourse, refreshView, filterCourses, clear
})

const weekdayMap = {
  1: "星期一",
  2: "星期二",
  3: "星期三",
  4: "星期四",
  5: "星期五",
  6: "星期六",
  0: "星期日",
}

</script>

<template>
  <div class="w-full max-w-full calendar-container">
    <q-calendar-scheduler
        class="w-full" bordered ref="qcalendarView" style="--calendar-resources-width: 40px"
        :weekdays="[1,2,3,4,5,6,0]"
        v-model="displayDate"
        :now="displayDate"
        view="week"
        v-model:model-resources="resources" resource-key="id" resource-label="name"
        :resource-height="cellHeight"
        locale="zh-HANS" :key="refreshFlag"
    >

      <template #head-day="{ scope }">
        <div class="text-center h-full">
          {{ weekdayMap[scope.timestamp.weekday] }}
        </div>
      </template>

      <template #resource-days="{ scope }">
        <template v-for="schedule in getGirdScheduleObject(scope)" :key="schedule">
          <q-btn multi-line flat text-color="white"
                 class="course-card flex-center p-1 bg-blue-500 cursor-default"
                 unelevated no-caps
                 @click="() => showDetail(schedule.info)"
                 :style="getStyle(schedule)">
            <p class="course-text text-center text-sm sm:text-base">
              {{ schedule.info.name ? schedule.info.name : schedule.info.courseName }}<br>
              <span class="course-count-text mt-1">
                {{ schedule.info.place }}<br>
                {{ schedule.info.startWeek }}-{{ schedule.info.endWeek }}周
              </span>
            </p>
          </q-btn>
        </template>
      </template>

    </q-calendar-scheduler>

    <q-dialog transition-show="fade" transition-hide="fade" v-model="detailDialogOpenState">
      <q-card class="activity-dialog">
        <div class="sticky top-0 bg-white z-10">
          <q-card-section>
            <div class="text-h6">课程信息</div>
          </q-card-section>
          <q-separator/>
        </div>

        <q-card-section class="scroll">
          <table>
            <tr>
              <td>课程ID：</td>
              <td>{{ currentSchedule.courseId }}</td>
            </tr>
            <tr>
              <td>课堂ID：</td>
              <td>{{ currentSchedule.scheduleId }}</td>
            </tr>
            <tr>
              <td>课程名称：</td>
              <td>{{ currentSchedule.courseName }}</td>
            </tr>
            <tr>
              <td>课时：</td>
              <td>{{ currentSchedule.courseHours }}</td>
            </tr>
            <tr>
              <td>周次：</td>
              <td>{{ currentSchedule.startWeek }}-{{ currentSchedule.endWeek }}周</td>
            </tr>
            <tr>
              <td>时间：</td>
              <td>第{{ currentSchedule.time + 1 }}大节，星期{{ numbers[currentSchedule.weekday] }}</td>
            </tr>
            <tr>
              <td>上课地点：</td>
              <td>{{ currentSchedule.place }}</td>
            </tr>
            <tr>
              <td>学期：</td>
              <td>{{ currentSchedule.academicTerm }}，{{ currentSchedule.springTerm ? '春季期' : '秋季期' }}</td>
            </tr>
            <tr>
              <td>考试成绩占比：</td>
              <td>{{ currentSchedule.examRatio }}</td>
            </tr>
          </table>
        </q-card-section>

        <div class="sticky bottom-0 bg-white z-10">
          <q-separator/>
          <q-card-actions align="right">
            <q-btn flat v-close-popup>好的</q-btn>
            <slot name="actions" :scheduleInfo="currentSchedule"></slot>
          </q-card-actions>
        </div>

      </q-card>
    </q-dialog>

    <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" scoped>
*
  transition: all 0.2s linear 0s

.course-count-text
  font-size: 0.6rem

@media not all and (min-width: 400px)
  .course-card
    padding: 2px
  .course-text
    font-size: 0.6rem
  .week-selector
    width: 100%
</style>
