<!--
* @FileDescription: 日历
* @Author: 黄琪勇
* @Date:2024-03-28 19:43:30
-->
<template>
   <el-calendar ref="calendarDom" :class="{ isNowMonth: isNowMonth }" class="h-calendar" v-model="dateData" v-bind="$attrs">
      <template #header="{}">
         <div class="calendarHead">
            <div class="tit">{{ format(dateData, "yyyy年mm月") }}</div>
            <div class="operate">
               <div class="left" @click="selectDate('prev-month')"></div>
               <div
                  class="mid"
                  :class="{ now: format(props.modelValue, 'yyyy/mm/dd') === format(new Date(), 'yyyy/mm/dd') }"
                  @click="selectDate('today')"
               ></div>
               <div class="right" @click="selectDate('next-month')"></div>
            </div>
         </div>
      </template>
      <template #date-cell="{ data }">
         <div class="dayCon" @click.stop>
            <div v-if="data.type === 'current-month'" :class="isMarkClass(data.day)" class="dayBox" @click.stop="handleClickDate(data)">
               <div class="daytit">
                  {{
                     format() === data.day && format(props.modelValue, "yyyy/mm/dd") !== format(new Date(), "yyyy/mm/dd")
                        ? "今"
                        : format(data.day, "d")
                  }}
               </div>
            </div>
            <div v-else class="nobg"></div>
         </div>
      </template>
   </el-calendar>
</template>

<script setup lang="ts">
import { format } from "@/libs/tools"
import { ref, computed, watch } from "vue"
import type { CalendarDateType, CalendarInstance } from "element-plus"
import { useLocale } from "element-plus"
import dayjs from "dayjs"

const props = defineProps<{
   modelValue: Date
   dayMarks?: string[]
}>()

const emits = defineEmits<{
   (e: "update:modelValue", value: Date): void
   (e: "monthChange", value: Date): void
}>()

const isNowMonth = computed(() => {
   return dateData.value.getMonth() === props.modelValue.getMonth() && dateData.value.getFullYear() === props.modelValue.getFullYear()
})
const isMarkClass = (date: string) => {
   if (!props.dayMarks) {
      return ""
   }
   const index = props.dayMarks.findIndex(day => {
      return format(day) === format(date)
   })
   if (index === -1) {
      return ""
   }
   return new Date(date.replace(/-/g, "/")) < new Date(format(new Date(), "yyyy/mm/dd")) ? "old" : "new"
}
const { lang } = useLocale()
const dateData = ref(props.modelValue)

watch(isNowMonth, () => {
   if (isNowMonth.value) dateData.value = props.modelValue
})
watch(dateData, (newVal, oldVal) => {
   if (newVal.getMonth() !== oldVal.getMonth()) {
      emits("monthChange", newVal)
   }
})

const calendarDom = ref<CalendarInstance>()
const selectDate = (val: CalendarDateType) => {
   calendarDom.value?.selectDate(val)
   if (val == "today") {
      emits("update:modelValue", dateData.value)
   }
}

function handleClickDate(data: { type: "prev-month" | "current-month" | "next-month"; isSelected: boolean; day: string; date: Date }) {
   calendarDom.value?.pickDay(dayjs(data.date).locale(lang.value))
   emits("update:modelValue", dateData.value)
}
</script>

<style lang="scss">
.h-calendar.el-calendar {
   --el-calendar-cell-width: 70px;
   background-color: #fff;
   .el-calendar__body {
      padding: 0;
   }
   /* 头部 */
   .el-calendar__header {
      padding: initial;
      border-bottom: none;
   }
   .el-calendar-table thead th {
      font-weight: 400;
      font-size: 24px;
      color: #777777;
      padding: 32px 0 18px 0;
   }
   .calendarHead {
      width: 100%;
      height: 42px;
      display: flex;
      justify-content: space-between;
      align-items: center;
      .tit {
         font-weight: 600;
         font-size: 30px;
         color: #333333;
      }
      .operate {
         display: flex;
         & > div {
            cursor: pointer;
            width: 38px;
            height: 38px;
         }
         .left {
            background: url("./img//left1.png") no-repeat;
            background-size: 100% 100%;
            &:hover {
               background-image: url("./img//left.png");
            }
         }
         .mid {
            margin: 0 28px;
            background: url("./img//midh.png") no-repeat;
            background-size: 100% 100%;
            &:hover,
            &.now {
               background: url("./img//mid.png") no-repeat;
               background-size: 100% 100%;
            }
         }
         .right {
            background: url("./img//right1.png") no-repeat;
            background-size: 100% 100%;
            &:hover {
               background-image: url("./img//right.png");
            }
         }
      }
   }
   /* 内容 */
   .el-calendar-table td {
      border: none;
      &.is-today {
         color: initial;
      }
      &.is-selected {
         background-color: initial;
      }
   }
   .el-calendar-table .el-calendar-day {
      height: initial;
      padding: 0;
      &:hover {
         cursor: initial;
         background-color: initial;
      }
   }
   .el-calendar-table tr td:first-child .el-calendar-day .dayCon {
      padding-left: 6px;
   }
   .el-calendar-table tr td:last-child .el-calendar-day .dayCon {
      padding-right: 6px;
   }
   .el-calendar-table tr:last-child td .el-calendar-day .dayCon {
      padding-bottom: 0px;
   }
   .el-calendar-table td {
      .el-calendar-day .dayCon {
         padding: 0 12px 12px 0;
         .dayBox {
            cursor: pointer;
            background: #f8f8f8;
            border-radius: 7px;
            height: var(--el-calendar-cell-width);
            display: flex;
            justify-content: center;
            align-items: center;
            color: #333333;
            font-family: DINAlternate, DINAlternate;
            font-weight: bold;
            font-size: 32px;
            &:hover {
               background: #fff7ed;
            }
            &.old .daytit {
               &::after {
                  content: "";
                  position: absolute;
                  width: 8px;
                  height: 8px;
                  border-radius: 50%;
                  bottom: -14px;
                  left: 50%;
                  transform: translateX(-50%);
                  background-color: #aaaaaa;
               }
            }
            &.new {
               background: #fff7ed;
               .daytit {
                  &::after {
                     content: "";
                     position: absolute;
                     width: 8px;
                     height: 8px;
                     border-radius: 50%;
                     bottom: -14px;
                     left: 50%;
                     transform: translateX(-50%);
                     background-color: #ff8057;
                  }
               }
            }
         }
         .nobg {
            height: var(--el-calendar-cell-width);
         }
         .daytit {
            font-weight: 600;
            font-size: 28px;
            position: relative;
         }
      }
      &.is-today .el-calendar-day .dayCon .dayBox {
         background-image: url("./img//jiao.png");
         background-size: 100% 100%;
         background-color: #fff7ed;
      }
   }
   &.isNowMonth .el-calendar-table td.is-selected .el-calendar-day .dayCon .dayBox {
      background: linear-gradient(45deg, #ffa357 0%, #ff6736 100%), #fff7ed;
      color: #ffffff;
      &.old .daytit,
      &.new .daytit {
         &::after {
            background-color: #fff;
         }
      }
   }
}
</style>
