<script setup lang="ts">
/* ================= learning mode ================= */
import PayDialog from '@/page/urge/opening/components/PayDialog.vue'
import { useRouter } from 'vue-router'
import dayjs from 'dayjs'
import urgeApi from '@/api/urge.ts'

const router = useRouter()

const learningMode = ref(1)
onActivated(() => {
  learningMode.value = 1
})
const learningModes = [
  { label: '1v1', value: 1 },
  { label: '1vN', value: 2 },
]

const modeList: Ref<anyObj[]> = ref([])
onBeforeMount(async () => {
  const {
    data: { data: res },
  } = await urgeApi.getInspectorModeList()
  modeList.value = res
})
const currentMode = computed(() => modeList.value.find(({ mode }) => mode === learningMode.value))

const selectableStartDay: Ref<dayjs.Dayjs | null> = ref(null)
onBeforeMount(async () => {
  const {
    data: { data: res },
  } = await urgeApi.getLastInspectorCourseInfo()
  selectableStartDay.value = (res ? dayjs(res.courseDate) : dayjs()).endOf('day')
})

/* ================= calendar ================= */
const today = dayjs()
const selectableDays = computed(() => {
  if (!selectableStartDay.value) {
    return []
  }
  const days = []
  let nextDay = dayjs(selectableStartDay.value).add(1, 'day')
  const endDay = selectableStartDay.value.add(1, 'month')
  while (nextDay.isBefore(endDay)) {
    if (nextDay.day() === 2 || nextDay.day() === 4 || nextDay.day() === 6) {
      days.push(nextDay.format('YYYY-MM-DD'))
    }
    nextDay = nextDay.add(1, 'day')
  }
  return days
})
const startDay: Ref<string | null> = ref(null)

onActivated(async () => {
  startDay.value = null
})

const selectedDays = computed(() => {
  if (!startDay.value) {
    return []
  }
  const days = []
  let day = dayjs(startDay.value)
  while (days.length < 12) {
    if (day.day() === 2 || day.day() === 4 || day.day() === 6) {
      days.push(day.format('YYYY-MM-DD'))
    }
    day = day.add(1, 'day')
  }
  return days
})
const calendarMaxDay = computed(() => {
  if (!startDay.value) {
    return today.date() === 1 ? today.endOf('month') : today.add(1, 'month')
  }
  return [...selectableDays.value, ...selectedDays.value]
    .map(date => dayjs(date))
    .reduce((max, current) => (current.isAfter(max) ? current : max))
})

function selectDay(day: string) {
  if (!selectableDays.value.includes(day)) {
    return
  }
  startDay.value = day
}

const activeMonth = ref(new Date())
const calendarHeight = computed(() => {
  const firstDay = dayjs(activeMonth.value).startOf('month')
  const totalDays = firstDay.daysInMonth()
  let startDayOfWeek = firstDay.day() - 1
  if (startDayOfWeek === -1) startDayOfWeek = 6
  const totalRows = Math.ceil((totalDays + startDayOfWeek) / 7)
  const pxValue = totalRows >= 6 ? 67.714285 : 79
  return (pxValue / 1200) * window.innerHeight + 'px'
})
const prevMonthVisible = computed(() => {
  const year = activeMonth.value.getFullYear()
  const month = activeMonth.value.getMonth()
  return year > today.year() || (year === today.year() && month > today.month())
})
const nextMonthVisible = computed(() => {
  const year = activeMonth.value.getFullYear()
  const month = activeMonth.value.getMonth()
  const maxYear = calendarMaxDay.value.year()
  const maxMonth = calendarMaxDay.value.month()
  return year < maxYear || (year === maxYear && month < maxMonth)
})

function nextMonth() {
  activeMonth.value = new Date(activeMonth.value.getFullYear(), activeMonth.value.getMonth() + 1)
}

function prevMonth() {
  activeMonth.value = new Date(activeMonth.value.getFullYear(), activeMonth.value.getMonth() - 1)
}

/* ================= schedules ================= */
const schedules = computed(() => {
  if (!startDay.value) {
    return []
  }
  return selectedDays.value.map((date, index) => ({
    date,
    time: '19:00-20:00',
    week: '星期' + ['日', '一', '二', '三', '四', '五', '六'][dayjs(date).day()],
    index: index + 1,
  }))
})

/* ================= price ================= */
const price = computed(() => {
  if (!startDay.value || modeList.value.length === 0) {
    return null
  }
  if (!currentMode.value) {
    return null
  }
  const { discount, discountPrice, price } = currentMode.value
  return { discount, discountPrice, price }
})

/* ================= buy ================= */
function handlePay() {
  if (!currentMode.value || !startDay.value) {
    return
  }
  payDialogVisible.value = true
}

/* ================= dialog ================= */
const payDialogVisible = ref(false)

function handlePayConfirm() {
  router.push('/urge/timetable')
}
</script>

<template>
  <div class="page">
    <div class="head">
      <BackBar />
      <ul class="learning-mode">
        <li
          v-for="mode in learningModes"
          :key="mode.value"
          :class="{ active: learningMode === mode.value }"
          @click="learningMode = mode.value"
        >
          {{ mode.label }}
        </li>
      </ul>
    </div>
    <div class="content">
      <div class="top">
        <div class="banner"></div>
        <div
          :class="{
            'price-info': true,
            pending: !price,
          }"
        >
          <template v-if="price && price.discount">
            <LineFont class="price-title" text="价格生成" size="40" />
            <LineFont class="price" color="#FFF01F" :text="`¥${price.discountPrice}`" size="64" />
            <div class="price-discount">
              <div class="price-original">¥{{ price.price }}</div>
              <div class="price-discount-amount">立减¥{{ price.price - price.discountPrice }}</div>
            </div>
          </template>
          <template v-else>
            <LineFont class="price-title" text="价格生成" size="48" />
            <LineFont
              class="price-pending"
              color="#FFF01F"
              :text="price?.price ?? '???'"
              size="72"
            />
          </template>
          <Btn class="buy-btn" :disabled="!currentMode || !startDay" tilt @click="handlePay"
            >购买
          </Btn>
        </div>
      </div>
      <div class="bottom">
        <div class="calendar">
          <div class="calendar-header">
            <div class="calendar-title">开课时间</div>
            <div class="month-navigation">
              <button v-if="prevMonthVisible" class="prev-month" @click="prevMonth"></button>
              <span class="month-title">{{ activeMonth.getMonth() + 1 }}月</span>
              <button v-if="nextMonthVisible" class="next-month" @click="nextMonth"></button>
            </div>
          </div>
          <div class="calendar-body">
            <el-calendar :model-value="activeMonth" class="calendar-table">
              <template #header>
                <div></div>
              </template>
              <template #date-cell="{ data }">
                <div
                  :class="{
                    'calendar-day': true,
                    'start-day': startDay === data.day,
                    disabled: !selectableDays.includes(data.day),
                    available: selectableDays.includes(data.day),
                    selected: selectedDays.includes(data.day),
                  }"
                  @click="selectDay(data.day)"
                >
                  {{ data.date.getDate() }}
                </div>
              </template>
            </el-calendar>
            <div class="calendar-legend">
              <span class="legend-item disabled">不可选</span>
              <span class="legend-item available">可选</span>
              <span class="legend-item selected">选中</span>
            </div>
          </div>
        </div>
        <div class="schedule">
          <div class="schedule-header">课表</div>
          <div class="schedule-body">
            <ul v-if="schedules.length > 0">
              <li v-for="item in schedules" :key="item.index">
                <span>{{ String(item.index).padStart(2, '0') }}</span>
                <span>{{ item.date }}</span>
                <span>{{ item.time }}</span>
                <span>{{ item.week }}</span>
              </li>
            </ul>
            <div v-else class="empty-tip">
              <img src="../assets/empty-tip.svg" alt="empty" />
              <p>请选择开课时间</p>
              <p>自动生成课表</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <PayDialog
      v-if="currentMode && startDay"
      v-model:visible="payDialogVisible"
      :startDay="startDay"
      :learningMode="currentMode"
      :price="currentMode.discountPrice"
      @confirm="handlePayConfirm"
    />
  </div>
</template>
<style scoped lang="scss">
.calendar-day {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  &.disabled {
    background: #ededed;
  }

  &.available {
    background: #f6f3fb;
  }

  &.selected {
    background: #c4b5ff;
  }

  &.start-day {
    &:after {
      font-family: OPPOSans, sans-serif;
      content: '开课时间';
      color: #fff;
      text-align: center;
      font-size: 1.33vh;
      line-height: 2vh;
      position: absolute;
      top: 0;
    }
  }
}

.empty-tip {
  color: #afbfcf;
  text-align: center;
  font-family: $font-special, sans-serif;
  font-size: 2vh;
  line-height: 3vh;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.price-title {
  margin-top: 2.67vh;
}

.price-pending {
  margin-top: 2.33vh;
}

.price {
  margin-top: 1.33vh;
}

.price-info {
  position: relative;
  width: 456px;
  height: 31.5vh;
  border-radius: 1.33vh;
  background: linear-gradient(180deg, #fafafa 0%, #f4f0fa 100%);
  margin-left: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;

  &:before {
    display: block;
    content: ' ';
    background: url('../assets/bg-stamp.svg') no-repeat center;
    background-size: cover;
    width: 229px;
    height: 15.75vh;
    position: absolute;
    right: 0;
    bottom: 0.33vh;
    pointer-events: none;
  }
}

.price-original {
  text-decoration: line-through;
}

.price-discount {
  margin-top: 1.17vh;
  display: flex;
  align-items: center;
  font-family: $font-special, sans-serif;
  font-size: 2.67vh;
  line-height: 4vh;
  color: #999;
}

.price-discount-amount {
  color: #f00a0a;
  margin-left: 16px;
}

.buy-btn {
  margin-top: 1.33vh;

  .pending & {
    margin-top: 2vh;
  }
}

.schedule {
  width: 844px;
  background: linear-gradient(180deg, #fafafa 0%, #f4f0fa 100%), #fff;
  filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
  border-radius: 1.33vh;
  margin-left: 24px;
  overflow: hidden;
}

.schedule-body {
  position: relative;
  padding: 1.33vh 16px 0;
  height: 43.83vh;
  overflow: auto;

  li {
    border-radius: 1.33vh;
    background: linear-gradient(90deg, #c3b4ff 0%, #fff 100%);
    height: 4.83vh;
    display: flex;
    align-items: center;
    text-align: center;

    + li {
      margin-top: 0.67vh;
    }

    &:nth-child(2n) {
      background: linear-gradient(90deg, rgba(196, 181, 255, 0.25) 0%, #fff 100%);
    }

    span:first-child {
      width: 10%;
    }

    span:nth-child(2) {
      width: 30%;
    }

    span:nth-child(3) {
      width: 30%;
    }

    span:last-child {
      width: 30%;
    }
  }
}

.schedule-header {
  color: $font-color;
  height: 6.67vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: $font-special, sans-serif;
  font-size: 3.33vh;
  line-height: 5vh;
  text-align: center;
  background:
    url('../assets/bg-mesh.svg') left bottom,
    linear-gradient(269deg, #adadff 2.25%, #cab5ff 51.93%, #8f9df7 99.65%);
  text-shadow:
    -2px -2px 0 #fff,
    2px -2px 0 #fff,
    -2px 2px 0 #fff,
    2px 2px 0 #fff,
    0px 4px 2px rgba(0, 0, 0, 0.25);
}

.calendar {
  width: 924px;
  height: 542px + 80px;
  border-radius: 1.33vh;
  overflow: hidden;
  background: #fff;
  filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));

  :deep(.el-calendar__header) {
    display: none;
  }

  :deep(.el-calendar__body) {
    padding: 0;

    table {
      table-layout: auto;
    }

    th {
      background: #ece5ff;
    }

    th,
    td {
      border: none;
    }

    th,
    .el-calendar-day {
      position: relative;
      padding: 0;
      height: v-bind(calendarHeight);
    }

    .prev,
    .next {
      .calendar-day {
        color: #ccc;
        background: #fafafa;
      }
    }

    .el-calendar-day,
    .el-calendar-day:hover {
      background: transparent;
    }

    .is-selected,
    .is-selected:hover {
      background: transparent;
    }

    th {
      color: $font-color;
      font-family: $font-special, sans-serif;
      font-size: 2vh;
      line-height: 3vh;
    }

    .el-calendar-day {
      color: $font-color;
      font-family: $font-special, sans-serif;
      font-size: 2.33vh;
      line-height: 3.5vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    tr {
      position: relative;
    }

    tr::after {
      content: '';
      position: absolute;
      height: 0.17vh;
      top: 0;
      width: 100%;
      left: 0;
      background: repeating-linear-gradient(
        to right,
        #cfc8e3,
        #cfc8e3 8px,
        transparent 8px,
        transparent 16px
      );
    }

    th,
    td {
      position: relative;

      &:not(:last-child):after {
        z-index: 1;
        content: '';
        position: absolute;
        height: 100%;
        bottom: 0;
        right: 0;
        width: 2px;
        background: repeating-linear-gradient(
          to bottom,
          #cfc8e3,
          #cfc8e3 8px,
          transparent 8px,
          transparent 16px
        );
      }
    }
  }
}

.calendar-table {
  height: 39.5vh;
  overflow: auto;
  background: rgba(0, 0, 0, 0.05);
  border-radius: 0 0 1.33vh 1.33vh;
}

.calendar-header {
  height: 6.67vh;
  color: $font-color;
  text-align: center;
  font-family: $font-special, sans-serif;
  font-size: 3.33vh;
  font-style: normal;
  font-weight: 400;
  line-height: 5vh;

  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 24px 0 24px;

  background:
    url('../assets/bg-mesh.svg') left bottom,
    linear-gradient(269deg, #adadff 2.25%, #cab5ff 51.93%, #8f9df7 99.65%);

  text-shadow:
    -2px -2px 0 #fff,
    2px -2px 0 #fff,
    -2px 2px 0 #fff,
    2px 2px 0 #fff,
    0px 4px 2px rgba(0, 0, 0, 0.25);
}

.calendar-legend {
  display: flex;
  justify-content: center;
  height: 5.67vh;
  align-items: center;

  color: $font-color;
  font-family: $font-special, sans-serif;
  font-size: 2vh;
  font-style: normal;
  font-weight: 400;
  line-height: 3vh;

  .legend-item {
    border-radius: 2.75vh;
    display: flex;
    align-items: center;

    + .legend-item {
      margin-left: 72px;
    }

    &:before {
      content: ' ';
      display: inline-block;
      width: 56px;
      height: 2vh;
      border-radius: 2.67vh;
      margin-right: 16px;
      box-shadow: 0 0.17vh 0.17vh 0 rgba(0, 0, 0, 0.25);
    }

    &.disabled:before {
      background: #ededed;
    }

    &.available:before {
      background: #f6f3fb;
    }

    &.selected:before {
      background: #c4b5ff;
    }
  }
}

.month-navigation {
  display: flex;
  align-items: center;
  column-gap: 16px;

  button {
    background: url('../assets/nav-prev.svg') no-repeat center;
    background-size: 100%;
    width: 48px;
    height: 4vh;
  }

  .next-month {
    background-image: url('../assets/nav-next.svg');
  }
}

.bottom {
  margin-top: 2vh;
  display: flex;
}

.top {
  margin-top: 0.67vh;
  padding: 0.67vh;
  border-radius: 1.33vh;
  background: linear-gradient(180deg, rgba(241, 234, 250, 0.35) 0%, rgba(241, 241, 250, 0.35) 100%);
  filter: drop-shadow(0px 4px 4px rgba(0, 0, 0, 0.25));
  display: flex;
}

.banner {
  border-radius: 1.33vh;
  background: linear-gradient(180deg, #fafafa 0%, #f4f0fa 100%);
  width: 1312px;
  height: 31.5vh;
}

.learning-mode {
  margin-left: 230px;
  width: 1172px;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(3px);
  border-radius: $space-2;
  color: #bdbfc3;
  text-align: center;
  font-family: $font-special, sans-serif;
  font-size: 2.67vh;
  font-weight: 400;
  line-height: 4vh;
  height: 4.83vh;
  padding: 0.33vh;
  display: flex;

  li {
    display: flex;
    flex: 1;
    height: 4.17vh;
    align-items: center;
    justify-content: center;

    &.active {
      color: $font-color;

      border-radius: 1.33vh;
      background: linear-gradient(269deg, #adadff 2.25%, #cab5ff 51.93%, #8f9df7 99.65%);
      backdrop-filter: blur(3px);
    }
  }
}

.page {
  width: 100%;
  height: 100%;
  @include main_bg;
  padding: $space-4_h $space-6;

  .head {
    display: flex;
    align-items: center;
  }
}
</style>
