<template>
  <view class="zzx-calendar">
    <view class="calendar-header">{{ timeStr }}</view>
    <!-- 星期几标题 -->
    <view class="calendar-weeks">
      <view
        class="calendar-week"
        :class="{ 'text-red-500': week === '六' || week === '日' }"
        v-for="(week, index) in data.weeks"
        :key="index"
      >{{ week }}</view>
    </view>

    <view class="calendar-content">
      <swiper
        class="calendar-swiper"
        :style="{
          width: '100%',
          height: calenderHeight,
        }"
        :indicator-dots="false"
        :autoplay="false"
        :duration="500"
        :current="data.current"
        @change="changeSwp"
        :circular="true"
      >
        <swiper-item class="calendar-item" v-for="sItem in data.swiper" :key="sItem">
          <view class="calendar-days">
            <!-- 当前的 -->
            <template v-if="sItem === data.current">
              <view
                class="calendar-day"
                v-for="(item, index) in data.days"
                :key="index"
                :class="{ 'day-hidden': !item.show }"
                @click="clickItem(item)"
              >
                <view
                  class="date"
                  :class="[item.isToday ? 'is-today' : '', item.fullDate === data.selectedDate ? 'is-checked' : '']"
                >{{ item.time.getDate() }}</view>
                <view class="dot-show" v-if="item.info === '0'" :style="dotStyle"></view>
              </view>
            </template>

            <template v-else>
              <!-- 下一个月/周 -->
              <template v-if="data.current - sItem === 1 || data.current - sItem === -2">
                <view
                  class="calendar-day"
                  v-for="(item, index) in preDays"
                  :key="index"
                  :class="{
                    'day-hidden': !item.show,
                  }"
                >
                  <view class="date" :class="[item.isToday ? 'is-today' : '']">{{ item.time.getDate() }}</view>
                </view>
              </template>

              <!-- 上一个月/周 -->
              <template v-else>
                <view
                  class="calendar-day"
                  v-for="(item, index) in nextDays"
                  :key="index"
                  :class="{
                    'day-hidden': !item.show,
                  }"
                >
                  <view class="date" :class="[item.isToday ? 'is-today' : '']">{{ item.time.getDate() }}</view>
                </view>
              </template>
            </template>
          </view>
        </swiper-item>
      </swiper>

      <!-- <view class="mode-change" @click="changeMode">
        <view :class="weekMode ? 'mode-arrow-bottom' : 'mode-arrow-top'"> </view>
      </view>-->
    </view>

    <view class="flex justify-center u-font-18" style="color: #3b82f6" @click="goToday">今日</view>
  </view>
</template>

<script setup>
import { reactive, computed, watchEffect } from 'vue';
import { useStore } from 'vuex';
import dayjs from 'dayjs';
import { generateDates, formatDate } from './generateDates.js';

const props = defineProps({
  // 打点日期的自定义样式
  dotStyle: {
    type: Object,
    default: () => ({ background: '#4ade80' }),
  },
});

const emit = defineEmits(['handleFindPoint', 'days-change', 'selected-change']);

const data = reactive({
  weeks: ['日', '一', '二', '三', '四', '五', '六'], // 周
  current: 1,
  currentYear: '',
  currentMonth: '',
  currentDate: '',
  days: [],
  weekMode: false, // false -> 月  true -> 显示周
  swiper: [0, 1, 2],
  selectedDate: formatDate(new Date(), 'yyyy-MM-dd'), // 当前选中的日期
  start: dayjs().startOf('month').valueOf(),
  end: dayjs().endOf('month').valueOf(),
});
const store = useStore();
const dotList = computed(() => store.state.project.dotList);
const calenderHeight = computed(() => {
  // 根据年月判断有多少行
  // 判断该月有多少天
  let h = '35px';
  if (!data.weekMode) {
    const d = new Date(data.currentYear, data.currentMonth, 0);
    const days = d.getDate(); // 判断本月有多少天
    const day = new Date(d.setDate(1)).getDay();
    // if (day === 0) {
    //   day = 7;
    // }
    const pre = 8 - day;
    const rows = Math.ceil((days - pre) / 7) + 1;
    h = `${35 * rows}px`;
  }
  return h;
});
// 当前日期 年月
const timeStr = computed(() => {
  let str = '';
  const d = new Date(data.currentYear, data.currentMonth - 1, data.currentDate);
  const y = d.getFullYear();
  const m = d.getMonth() + 1 <= 9 ? `0${d.getMonth() + 1}` : d.getMonth() + 1;
  str = `${y}年${m}月`;
  return str;
});
// 上一周期的days书籍
const preDays = computed(() => {
  let pres = [];
  if (data.weekMode) {
    // 周模式
    const d = new Date(data.currentYear, data.currentMonth - 1, data.currentDate);
    d.setDate(d.getDate() - 7);
    pres = generateDates(d, 'week');
  } else {
    // 月模式
    const d = new Date(data.currentYear, data.currentMonth - 2, 1);
    pres = generateDates(d, 'month');
  }
  return pres;
});
// 下一周期的days书籍
const nextDays = computed(() => {
  let next = [];
  if (data.weekMode) {
    // 周模式
    const d = new Date(data.currentYear, data.currentMonth - 1, data.currentDate);
    d.setDate(d.getDate() + 7);
    next = generateDates(d, 'week');
  } else {
    // 月模式
    const d = new Date(data.currentYear, data.currentMonth, 1);
    next = generateDates(d, 'month');
  }
  return next;
});

watchEffect(() => {
  const days = data.days.slice(0);
  const index = days.findIndex(day => day.show);
  days.forEach((day, i) => {
    dotList.value.forEach((item, j) => {
      if (i - index === j) {
        day.info = item;
      }
    });
  });
  data.days = days;
});

// 初始化日历的方法
const initDate = cur => {
  let date = '';
  if (cur) {
    date = new Date(cur);
  } else {
    date = new Date();
  }
  data.currentDate = date.getDate(); // 今日几号
  data.currentYear = date.getFullYear(); // 当前年份
  data.currentMonth = date.getMonth() + 1; // 当前月份
  data.currentWeek = date.getDay() === 0 ? 7 : date.getDay(); // 1...6,0 星期几
  // const nowY = new Date().getFullYear(); // 当前年份
  // const nowM = new Date().getMonth() + 1;
  // const nowD = new Date().getDate(); // 今日日期 几号
  // const nowW = new Date().getDay();
  // this.selectedDate = formatDate(new Date(), 'yyyy-MM-dd')
  data.days = [];
  let days = [];
  if (data.weekMode) {
    days = generateDates(date, 'week');
    // this.selectedDate = days[0].fullDate;
  } else {
    days = generateDates(date, 'month');

    // const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
    // const isMonth = sel.getFullYear() === this.currentYear && (sel.getMonth() + 1) === this.currentMonth;
    // if(!isMonth) {
    // 	this.selectedDate = formatDate(new Date(this.currentYear, this.currentMonth-1,1), 'yyyy-MM-dd')
    // }
  }

  // 设置小红点
  days.forEach((day, i) => {
    dotList.value.forEach((item, j) => {
      if (i === j) {
        day.info = item;
      }
    });
  });

  data.days = days;
  // 派发事件,时间发生改变
  const obj = {
    start: '',
    end: '',
  };
  if (data.weekMode) {
    obj.start = data.days[0].time;
    obj.end = data.days[6].time;
  } else {
    const start = new Date(data.currentYear, data.currentMonth - 1, 1);
    const end = new Date(data.currentYear, data.currentMonth, 0);
    obj.start = start;
    obj.end = end;
  }
  emit('days-change', obj);
};

initDate();

//  上一个
const daysPre = () => {
  if (data.weekMode) {
    const d = new Date(data.currentYear, data.currentMonth - 1, data.currentDate);
    d.setDate(d.getDate() - 7);
    initDate(d);
  } else {
    const d = new Date(data.currentYear, data.currentMonth - 2, 1);
    initDate(d);
  }
};

//  下一个
const daysNext = () => {
  if (data.weekMode) {
    const d = new Date(data.currentYear, data.currentMonth - 1, data.currentDate);
    d.setDate(d.getDate() + 7);
    initDate(d);
  } else {
    const d = new Date(data.currentYear, data.currentMonth, 1);
    initDate(d);
  }
};

/**
 * 滑动切换上下周期
 * 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周
 * current - pre === 1, -2 下一个月/周
 * current - pre === -1, 2 上一个月或者上一周
 */
const changeSwp = e => {
  const pre = data.current;
  const { current } = e.detail;
  data.current = current;
  if (current - pre === 1 || current - pre === -2) {
    // 下一个月 或 下一周
    daysNext();
    const arr = data.days.filter(s => s.show);
    const end = `${arr[arr.length - 1].fullDate} 23:59:59`;
    data.start = dayjs(arr[0].fullDate).valueOf();
    data.end = dayjs(end).valueOf();
    emit('handleFindPoint', data.start, data.end);
  } else {
    // 上一个月 或 上一周
    daysPre();
    const arr = data.days.filter(s => s.show);
    const end = `${arr[arr.length - 1].fullDate} 23:59:59`;
    data.start = dayjs(arr[0].fullDate).valueOf();
    data.end = dayjs(end).valueOf();
    emit('handleFindPoint', data.start, data.end);
  }
};

// 切换模式
// const changeMode = () => {
// const premode = this.weekMode;
// let isweek = false;
// if (premode) {
//   isweek = !!this.days.find((item) => item.fullDate === this.selectedDate);
// }
// this.weekMode = !this.weekMode;
// let d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate);
// const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
// const isMonth = sel.getFullYear() === this.currentYear && sel.getMonth() + 1 === this.currentMonth;
// if ((this.selectedDate && isMonth) || isweek) {
//   d = new Date(this.selectedDate.replace('-', '/').replace('-', '/'));
// }
// this.initDate(d);
// };

// 点击日期
const clickItem = e => {
  data.selectedDate = e.fullDate;
  emit('selected-change', e);
};

// 返回
const goToday = () => {
  const d = new Date();
  d.fullDate = dayjs(d).format('YYYY-MM-DD');
  data.selectedDate = d.fullDate;
  // initDate(d);
  emit('selected-change', d);
};
</script>

<style lang="scss" scoped>
.zzx-calendar {
  width: 100%;
  height: auto;
  background-color: #fff;
  padding-bottom: 10px;

  .calendar-header {
    text-align: center;
    padding: 16px 0;
    position: relative;
    font-size: 15px;
  }

  .calendar-weeks {
    width: 100%;
    display: flex;
    flex-flow: row nowrap;
    margin-bottom: 10px;
    justify-content: center;
    align-items: center;
    font-size: 12px;
    color: #9ca3af;
    font-weight: bold;

    .calendar-week {
      width: calc(100% / 7);
      height: 100%;
      text-align: center;
    }
  }
  swiper {
    width: 100%;
    height: 60upx;
  }
  .calendar-content {
    min-height: 30px;
  }
  .calendar-swiper {
    min-height: 35px;
    transition: height ease-out 0.3s;
  }
  .calendar-item {
    margin: 0;
    padding: 0;
    height: 100%;
  }
  .calendar-days {
    display: flex;
    flex-flow: row wrap;
    width: 100%;
    height: 100%;
    overflow: hidden;
    font-size: 14px;

    .calendar-day {
      width: calc(100% / 7);
      height: 35px;
      text-align: center;
      display: flex;
      flex-flow: column nowrap;
      justify-content: flex-start;
      align-items: center;
      position: relative;
    }
  }
  .day-hidden {
    visibility: hidden;
  }

  .mode-change {
    display: flex;
    justify-content: center;
    margin-top: 5px;

    .mode-arrow-top {
      width: 0;
      height: 0;
      border-left: 6px solid transparent;
      border-right: 6px solid transparent;
      border-bottom: 5px solid #ff6633;
    }
    .mode-arrow-bottom {
      width: 0;
      height: 0;
      border-left: 6px solid transparent;
      border-right: 6px solid transparent;
      border-top: 5px solid #ff6633;
    }
  }
  .is-today {
    background: #ffffff;
    border: 1upx solid #ff6633;
    border-radius: 50%;
    color: #ff6633;
  }
  .is-checked {
    background: #ff6633;
    color: #ffffff;
  }
  .date {
    width: 25px;
    height: 25px;
    line-height: 25px;
    margin: 0 auto;
    border-radius: 25px;
  }
  .dot-show {
    width: 6px;
    height: 6px;
    // background: red;
    border-radius: 5px;
    position: absolute;
    top: 2px;
    right: 10px;
  }
}
</style>
