<script setup>
import {QCalendarScheduler, today} 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";
import courseApi from "app/src/api/course/course";
import StudentCourseSelectingConfirmPane from "pages/student/course/view/StudentCourseSelectingConfirmPane.vue";
import {useRouter} from "vue-router";
import {useCurrentActivityStore} from "stores/activity";
import courseScheduleApi from "app/src/api/course/course_schedule";

const quasar = useQuasar()

const props = defineProps({
  courseList: {
    type: Array,
    default() {
      return [{
        id: "test_2654ed5beb59",
        name: "test_5620380e9d17",
        course: "test_5503f4b7657d",
        startWeek: 71,
        endWeek: 80,
        time: 64,
        weekday: 34,
        academicTerm: "test_53ddcf34d0bf",
        place: "test_b93b16f1e404",
        ratio: 94.64,
        distribution: {},
        teachers: [
          {
            id: "test_7feb0925d461",
            name: "test_cb0ef7558eb8",
            createTime: "2019-06-17 20:51:26",
            editTime: "2025-03-30 22:34:44",
            deleted: false
          }
        ]
      }]
    }
  }
})

const cellHeight = 120

const toDay = dayjs()
const displayDate = toDay.format("YYYY-MM-DD")
const selectedDate = 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: [],
}

function loadCourse(courseList) {
  clear()

  courseList.forEach(course => addCourse(course, false))

  refreshView()
}

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

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

  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),
        id: course.id,
        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 clickedSchedule = ref({})

const confirmDialogState = ref(false)
const confirmPane = ref()

async function openOrCloseConfirmPane(schedule) {
  if (confirmDialogState.value === false) {
    loading.value = true
    try {
      await confirmPane.value.init(schedule)
      confirmDialogState.value = true
    } catch (e) {
      console.warn(e)
      quasar.dialog({
        transitionShow: 'fade',
        transitionHide: 'fade',
        title: '啊哈？',
        message: e.message
      })
    } finally {
      loading.value = false
    }
  }
}

function showOfficialDetail(schedule) {
  quasar.dialog({
    transitionShow: 'fade',
    transitionHide: 'fade',
    title: '课程信息',
    html: true,
    message: `
        <p style="padding-bottom: .5rem;"><strong>课程名称：</strong>&emsp;${schedule.name}<br></p>
        <p style="padding-bottom: .5rem;"><strong>周次：</strong>&emsp;&emsp;&emsp;${schedule.startWeek}-${schedule.endWeek}周<br></p>
        <p style="padding-bottom: .5rem;"><strong>节次：</strong>&emsp;&emsp;&emsp;第${schedule.time + 1}大节，星期${numbers[schedule.weekday]}<br></p>
        <p style="padding-bottom: .5rem;"><strong>上课地点：</strong>&emsp;${schedule.place}<br></p>
    `,
  })
}

const activityStore = useCurrentActivityStore()
let activity = {}

async function init() {
  activity = await activityStore.loadCurrentActivity()
}

init()

function select(schedule) {
  const conflict = checkConflict(schedule)
  if (conflict !== undefined) {
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '真的？',
      cancel: true,
      message: `所选的时间可能与现有的课程『${conflict.name}』冲突，确定要选吗？`
    })
      .onOk(() => {
        selectSchedule(schedule.id, activity.value.id)
      })
  } else {
    selectSchedule(schedule.id, activity.value.id)
  }
}

async function unselect(schedule) {
  loading.value = true
  try {
    await courseApi.student.unselect(schedule.id)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '好啦',
      message: '好啦',
    })
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  } finally {
    loading.value = false
  }
}

const router = useRouter()

async function selectSchedule(scheduleId, activityId) {
  loading.value = true
  try {
    await courseApi.student.select(scheduleId, activityId)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '好啦',
      message: '好啦'
    })
  } catch (e) {
    console.warn(e)
    quasar.dialog({
      transitionShow: 'fade',
      transitionHide: 'fade',
      title: '啊哈？',
      message: e.message
    })
  } finally {
    loading.value = false
  }
}

function checkConflict(schedule) {
  let rowCourses = displayCourses[schedule.time]
  for (let i = 0; rowCourses !== undefined && i < rowCourses.length; i++) {
    const course = rowCourses[i];
    if (course.weekday === schedule.weekday && course.id !== schedule.id) {
      return course
    }
  }

  return undefined
}

defineExpose({
  loadCourse, addCourse, refreshView
})

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="() => schedule.official ? showOfficialDetail(schedule.info) : openOrCloseConfirmPane(schedule.info)"
                 :style="getStyle(schedule)">
            <span class="course-text text-center text-xs">
              {{ schedule.info.place }}<br>
              {{ schedule.info.startWeek }}-{{ schedule.info.endWeek }}周
            </span>
          </q-btn>
        </template>
      </template>
    </q-calendar-scheduler>

    <StudentCourseSelectingConfirmPane ref="confirmPane" v-model:open="confirmDialogState"
                                       v-model:course-schedule="clickedSchedule"
                                       @on-ok="select" @on-delete="unselect"/>

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