<template>
  <view class="calendar-box">
    <view class="calendar-wrapper">
      <view v-if="headerSlot">
        <slot name="header" :date="{ monthDate: currentDateStr, date: dateForm.currentDay }"></slot>
      </view>
      <view v-if="showHeader && !headerSlot" class="calendar-toolbar">
        <view class="current" @click="dateForm.showMonthPicker = true">
          {{ currentDateStr }}
        </view>
        <view class="steps">
          <view class="step prev" @click="prevMonth">
            <wd-icon name="arrow-left" size="30rpx"></wd-icon>
          </view>
          <view class="step next" @click="nextMonth">
            <wd-icon name="arrow-right" size="30rpx"></wd-icon>
          </view>
        </view>
      </view>

      <view class="calendar-week">
        <view v-for="item of weekList" :key="item" class="week-item calendarBorder">
          {{ item }}
        </view>
      </view>
      <view class="calendar-inner">
        <view
          v-for="(item, index) of calendarList"
          :key="index"
          :class="{
            'calendar-item': true,
            calendarBorder: true,
            'calendar-item-checked': dateForm.multipleList.includes(item.date),
            'disabled': item.disabled
          }"
          @click="handleClickDay(item)"
        >
          <view
            :class="{
              date: true,
              'calendar-item-hover': item.isCurrentMonth,
              'calendar-item-disabled': !item.isCurrentMonth,
              'calendar-item-current':
                dateForm.multipleList.includes(item.date) && item.isCurrentMonth,
            }"
            >{{ item.day }}</view
          >
          <view v-if="cellSlot">
            <slot name="cell" :date="item"></slot>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script setup lang="ts">
import { reactive, ref, computed, onMounted, watch, useSlots, nextTick } from 'vue';
import dayjs from 'dayjs';
import { type CalendarDay, generateMonthCalendar } from '@/utils/calendar';
const props = defineProps({
  minDate: {
    type: Date,
    // required: true,
  },
  maxDate: {
    type: Date,
    // required: true
  },
  auto: {
    type: Boolean,
    default: true,
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  limit: {
    type: Number,
    default: 0,
  },
  selectedDay: {
    type: String,
    // required: true,
    default: dayjs().format('YYYY-MM-DD'),
  },
  // 可选日期//默认所有可选
  canSeletion: {
    type: Array,
    default: [],
  },
  calendar: {
    type: Object,
    default: () => {},
  },
  calendarDays: {
    type: Array,
    default: [],
    // required: true,
  },
  showHeader: {
    type: Boolean,
    default: true,
  },
  IndexDayCount: {
    type: Array,
    default: [],
    // required: true,
  },
  dateDisabled: {
    type: Function
  }
});
const emits = defineEmits(['selectedDay', 'changeMonth', 'selection']);
const uSlot = useSlots();
const dateForm = reactive({
  showMonthPicker: false,
  currentDay: dayjs(new Date()).format('YYYY-MM-DD'),
  multipleList: [],
});
const weekList = ['一', '二', '三', '四', '五', '六', '日']; // 周
const monthFirstDay = ref(dayjs().startOf('month'));
const calendarList = computed(() => {
  return generateMonthCalendar(monthFirstDay.value.toDate()).flat().map(item => {
    return {
      ...item,
      disabled: props.dateDisabled && typeof props.dateDisabled === 'function' ? props.dateDisabled(item) : false
    }
  });
});
const currentDateStr = computed(() => {
  return dayjs(monthFirstDay.value).format('YYYY年MM月');
});
const headerSlot = computed(() => {
  return uSlot.header;
});
const cellSlot = computed(() => {
  return uSlot.cell;
});
watch(
  () => props.selectedDay,
  val => {
    nextTick(() => {
      // 非多选默认选中当天或者不默认选中
      if (!props.auto) {
        dateForm.multipleList = [];
      } else if (!props.multiple || props.auto) {
        dateForm.multipleList = [val];
      }
      monthFirstDay.value = dayjs(val).startOf('month');
    });
  },
  { immediate: true, deep: true },
);

const prevMonth = () => {
  monthFirstDay.value = monthFirstDay.value.subtract(1, 'month');
  setCurrentDay();
};

const nextMonth = () => {
  monthFirstDay.value = monthFirstDay.value.add(1, 'month');
  setCurrentDay();
};
function setCurrentDay() {
  if (!props.multiple) {
    const date = dayjs(monthFirstDay.value).format('YYYY-MM-DD');
    dateForm.multipleList = props.auto ? [date] : [];
    dateForm.currentDay = date;
  }
}
// 操作：点击了某天
function handleClickDay(item: any) {
  if (!item || !item.isCurrentMonth || item.disabled) return;
  if (props.canSeletion.length) {
    if (!props.canSeletion.includes(item.date)) {
      return;
    }
  }
  // 如果支持多选
  if (props.multiple) {
    if (dateForm.multipleList.includes(item.date)) {
      dateForm.multipleList = dateForm.multipleList.filter(date => date !== item.date);
    } else {
      if (dateForm.multipleList.length < props.limit || !props.limit) {
        dateForm.multipleList.push(item.date);
      }
    }
    emits('selection', dateForm.multipleList);
  } else {
    dateForm.multipleList = [item.date];
    dateForm.currentDay = item.date;
  }
  emits('selectedDay', item);
}
defineExpose({
  prevMonth,
  nextMonth,
});
</script>
<style lang="scss" scoped>
.calendar-box {
  width: 690rpx;
  min-height: 637rpx;
  display: flex;
  justify-content: space-around;
  align-items: center;
  // background: #fff;
  font-size: 28rpx;
  margin: 0 auto;
  .calendar-wrapper {
    border-radius: 20rpx;
    padding-top: 20rpx;
    box-sizing: border-box;
    background-color: #fff;
    .calendar-toolbar {
      width: 690rpx;
      height: 100rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      .steps {
        display: flex;
        margin-right: 20rpx;
      }
      .steps .step {
        width: 48rpx;
        height: 48rpx;
        color: #fff;
        display: flex;
        justify-content: center;
        align-items: center;
        background: #615dff;
        text-align: center;
        border-radius: 50%;
      }
      .prev,
      .next,
      .current {
        font-size: 32rpx;
        font-weight: 500;
        color: #333333;
        margin-left: 20rpx;
        cursor: pointer;
      }
      .van-icon-arrow-down {
        vertical-align: -15%;
      }
    }
    .calendar-week {
      width: 690rpx;
      border-bottom: 1rpx solid #e8e8e8;
      display: flex;
      flex-wrap: wrap;
      // justify-content: space-around;
      .week-item {
        width: calc(100% / 7);
        height: 50rpx;
      }
    }
    .calendar-inner {
      width: 690rpx;
      display: flex;
      flex-wrap: wrap;
      padding-bottom: 20rpx;
      .calendar-item {
        width: calc(100% / 7);
        min-height: 112rpx;
        position: relative;
        border-left: 1rpx solid #e8e8e8;
        border-bottom: 1rpx solid #e8e8e8;
        box-sizing: border-box;
        &.disabled {
          background-color: #f9f9f9;
        }
      }
      .calendar-item:nth-child(7n) {
        border-right: 1rpx solid #e8e8e8;
      }
      // .calendar-item:nth-child(7n+1){
      //     border-left: 0;
      // }
      .calendar-item-hover {
        cursor: pointer;
        //&:hover {
        // color: #000;
        // border-radius: 40rpx;
        // background: #ffffff;
        // box-shadow: 0 2rpx 30rpx 0 rgba(137, 138, 255, 0.55);
        //}
      }
      .calendar-item-disabled {
        color: #ccc !important;
        cursor: not-allowed;
      }
      .calendar-item-checked {
        color: #615dff !important;
        background-color: #f0f0ff;
      }
      .calendar-item-current {
        color: #615dff !important;
      }
      .date {
        text-align: center;
        font-size: 32rpx;
        line-height: 44rpx;
        color: #0a1f13;
      }
    }

    .calendarBorder {
      text-align: center;
      // display: flex;
      // justify-content: center;
      // align-items: center;
      // border-bottom: 1px solid #eee;
      // border-right: 1px solid #eee;
    }
  }
}
.van-popup--bottom.van-popup--round {
  border-radius: 24rpx 24rpx 0 0;
}
</style>
