<template>
  <view class="w-picker-view">
    <view
      style="
        display: flex;
        justify-content: space-around;
        font-size: 18px;
        font-weight: 700;
        padding: 30upx 0;
        border-bottom: 1rpx solid rgb(134 134 134);
        border-top: 1rpx solid rgb(134 134 134);
        color:#1936C9
      "
    >
      <view>年份</view>
      <view>月</view>
      <view>日</view>
      <view>场次</view>
    </view>

    <picker-view
      class="d-picker-view"
      :indicator-style="itemHeight"
      :value="pickVal"
      @change="handlerChange"
    >
      <picker-view-column>
        <view
          class="w-picker-item"
          v-for="(item, index) in range.years"
          :key="index"
          >{{ item }}</view
        >
      </picker-view-column>
      <picker-view-column>
        <view
          class="w-picker-item"
          v-for="(item, index) in range.months"
          :key="index"
          >{{ item }}</view
        >
      </picker-view-column>
      <picker-view-column>
        <view
          class="w-picker-item"
          v-for="(item, index) in range.days"
          :key="index"
          >{{ item }}</view
        >
      </picker-view-column>
      <picker-view-column>
        <view
          class="w-picker-item"
          v-for="(item, index) in range.sections"
          :key="index"
          >{{ item }}</view
        >
      </picker-view-column>
    </picker-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      pickVal: [],
      range: {},
      checkObj: {},
    };
  },
  props: {
    itemHeight: {
      type: String,
      default: "44px",
    },
    startYear: {
      type: String,
      default: "",
    },
    endYear: {
      type: String,
      default: "",
    },
    value: {
      type: [String, Array, Number],
      default: "",
    },
    current: {
      //是否默认选中当前日期
      type: Boolean,
      default: false,
    },
    disabledAfter: {
      //是否禁用当前之后的日期
      type: Boolean,
      default: false,
    },
    disabledBefore: {
      //是否禁用当前之前
      type: Boolean,
      default: true,
    },
  },
  watch: {
    value(val) {
      this.initData();
    },
  },
  created() {
    this.initData();
  },
  methods: {
    formatNum(n) {
      return Number(n) < 10 ? "0" + Number(n) : Number(n) + "";
    },
    checkValue(value) {
      let strReg = /^\d{4}-\d{2}-\d{2} [\u4e00-\u9fa5]{2}$/,
        example;
      if (!strReg.test(value)) {
        console.log(
          new Error(
            "请传入与mode、fields匹配的value值,例value=" + example + ""
          )
        );
      }
      return strReg.test(value);
    },
    resetData(year, month, day) {
      let curDate = this.getCurrenDate();
      let curFlag = this.current;
      let curYear = curDate.curYear;
      let curMonth = curDate.curMonth;
      let curDay = curDate.curDay;
      let curHour = curDate.curHour;
      let months = [],
        days = [],
        sections = [];
      let disabledAfter = this.disabledAfter;
      let monthsLen = disabledAfter ? (year * 1 < curYear ? 12 : curMonth) : 12;
      let totalDays = new Date(year, month, 0).getDate(); //计算当月有几天;
      let daysLen = disabledAfter
        ? year * 1 < curYear || month * 1 < curMonth
          ? totalDays
          : curDay
        : totalDays;
      let sectionFlag = disabledAfter
        ? (year * 1 < curYear || month * 1 < curMonth || day * 1 < curDay) ==
          true
          ? false
          : true
        : curHour > 12 == true
        ? true
        : false;

      sections = ["上午", "下午"];
      for (let month = 1; month <= monthsLen; month++) {
        months.push(this.formatNum(month));
      }
      for (let day = 1; day <= daysLen; day++) {
        days.push(this.formatNum(day));
      }
      return {
        months,
        days,
        sections,
      };
    },
    getData(dVal) {
      //用来处理初始化数据
      let curFlag = this.current;
      let disabledAfter = this.disabledAfter;
      let curDate = this.getCurrenDate();
      let curYear = curDate.curYear;
      let curMonthdays = curDate.curMonthdays;
      let curMonth = curDate.curMonth;
      let curDay = curDate.curDay;
      let curHour = curDate.curHour;
      let defaultDate = this.getDefaultDate();
      let startYear = this.getStartDate().getFullYear();
      let endYear = this.getEndDate().getFullYear();
      let years = [],
        months = [],
        days = [],
        sections = [];
      let year = dVal[0] * 1;
      let month = dVal[1] * 1;
      let day = dVal[2] * 1;
      let monthsLen = disabledAfter
        ? year < curYear
          ? 12
          : curDate.curMonth
        : 12;
      let daysLen = disabledAfter
        ? year < curYear || month < curMonth
          ? defaultDate.defaultDays
          : curDay
        : curFlag
        ? curMonthdays
        : defaultDate.defaultDays;
      let sectionFlag = disabledAfter
        ? (year * 1 < curYear || month * 1 < curMonth || day * 1 < curDay) ==
          true
          ? false
          : true
        : curHour > 12 == true
        ? true
        : false;
      for (
        let year = startYear;
        year <= (disabledAfter ? curYear : endYear);
        year++
      ) {
        years.push(year.toString());
      }
      for (let month = 1; month <= monthsLen; month++) {
        months.push(this.formatNum(month));
      }
      for (let day = 1; day <= daysLen; day++) {
        days.push(this.formatNum(day));
      }
      sections = ["上午", "下午"];
      if (this.disabledBefore) {
        years = years.filter((item) => item * 1 >= curYear);
        months = months.filter((item) => item * 1 >= curMonth);
        days = days.filter((item) => item * 1 >= curDay);

        let nowcurDate = new Date();
        let nowcurYear = nowcurDate.getFullYear();
        let nowcurMonth = nowcurDate.getMonth() + 1;
        let nowcurDay = nowcurDate.getDate();
        let nowcurHour = nowcurDate.getHours();
        if (
          curYear === nowcurYear &&
          curMonth === nowcurMonth &&
          curDay === nowcurDay &&
          nowcurHour > 12
        ) {
          sections = ["下午"];
        } else {
          sections = ["上午", "下午"];
        }
      }
      return {
        years,
        months,
        days,
        sections,
      };
    },
    getCurrenDate() {
      let curDate = new Date();
      let curYear = curDate.getFullYear();
      let curMonth = curDate.getMonth() + 1;
      let curMonthdays = new Date(curYear, curMonth, 0).getDate();
      let curDay = curDate.getDate();
      let curHour = curDate.getHours();
      let curSection = "上午";
      if (curHour >= 12) {
        curSection = "下午";
      }
      return {
        curDate,
        curYear,
        curMonth,
        curMonthdays,
        curDay,
        curHour,
        curSection,
      };
    },
    getDefaultDate() {
      let value = this.value;
      let reg = /-/g;
      let defaultDate = value
        ? new Date(value.split(" ")[0].replace(reg, "/"))
        : new Date();
      let defaultYear = defaultDate.getFullYear();
      let defaultMonth = defaultDate.getMonth() + 1;
      let defaultDay = defaultDate.getDate();
      let defaultDays = new Date(defaultYear, defaultMonth, 0).getDate() * 1;
      return {
        defaultDate,
        defaultYear,
        defaultMonth,
        defaultDay,
        defaultDays,
      };
    },
    getStartDate() {
      let start = this.startYear;
      let startDate = "";
      let reg = /-/g;
      if (start) {
        startDate = new Date(start + "/01/01");
      } else {
        startDate = new Date("1970/01/01");
      }
      return startDate;
    },
    getEndDate() {
      let end = this.endYear;
      let reg = /-/g;
      let endDate = "";
      if (end) {
        endDate = new Date(end + "/12/31");
      } else {
        endDate = new Date();
      }
      return endDate;
    },
    getDval() {
      let value = this.value;
      let dVal = null;
      let aDate = new Date();
      let year = this.formatNum(aDate.getFullYear());
      let month = this.formatNum(aDate.getMonth() + 1);
      let day = this.formatNum(aDate.getDate());
      let hour = aDate.getHours();
      let section = "上午";
      if (hour >= 12) section = "下午";
      if (value) {
        let flag = this.checkValue(value);
        if (!flag) {
          dVal = [year, month, day, section];
        } else {
          let v = value.split(" ");
          dVal = [...v[0].split("-"), v[1]];
        }
      } else {
        dVal = [year, month, day, section];
      }
      return dVal;
    },
    initData() {
      let startDate,
        endDate,
        startYear,
        endYear,
        startMonth,
        endMonth,
        startDay,
        endDay;
      let years = [],
        months = [],
        days = [],
        sections = [];
      let dVal = [],
        pickVal = [];
      let value = this.value;
      let reg = /-/g;
      let range = {};
      let result = "",
        full = "",
        year,
        month,
        day,
        section,
        obj = {};
      let defaultDate = this.getDefaultDate();
      let defaultYear = defaultDate.defaultYear;
      let defaultMonth = defaultDate.defaultMonth;
      let defaultDay = defaultDate.defaultDay;
      let defaultDays = defaultDate.defaultDays;
      let curFlag = this.current;
      let disabledAfter = this.disabledAfter;
      let curDate = this.getCurrenDate();
      let curYear = curDate.curYear;
      let curMonth = curDate.curMonth;
      let curMonthdays = curDate.curMonthdays;
      let curDay = curDate.curDay;
      let curSection = curDate.curSection;
      let dateData = [];
      dVal = this.getDval();
      startDate = this.getStartDate();
      endDate = this.getEndDate();
      startYear = startDate.getFullYear();
      startMonth = startDate.getMonth();
      startDay = startDate.getDate();
      endYear = endDate.getFullYear();
      endMonth = endDate.getMonth();
      endDay = endDate.getDate();
      dateData = this.getData(dVal);
      years = dateData.years;
      months = dateData.months;
      days = dateData.days;
      sections = dateData.sections;
      pickVal = disabledAfter
        ? [
            dVal[0] && years.indexOf(dVal[0]) != -1
              ? years.indexOf(dVal[0])
              : 0,
            dVal[1] && months.indexOf(dVal[1]) != -1
              ? months.indexOf(dVal[1])
              : 0,
            dVal[2] && days.indexOf(dVal[2]) != -1 ? days.indexOf(dVal[2]) : 0,
            dVal[3] && sections.indexOf(dVal[3]) != -1
              ? sections.indexOf(dVal[3])
              : 0,
          ]
        : curFlag
        ? [
            years.indexOf(curYear + ""),
            months.indexOf(this.formatNum(curMonth)),
            days.indexOf(this.formatNum(curDay)),
            sections.indexOf(curSection),
          ]
        : [
            dVal[0] && years.indexOf(dVal[0]) != -1
              ? years.indexOf(dVal[0])
              : 0,
            dVal[1] && months.indexOf(dVal[1]) != -1
              ? months.indexOf(dVal[1])
              : 0,
            dVal[2] && days.indexOf(dVal[2]) != -1 ? days.indexOf(dVal[2]) : 0,
            dVal[3] && sections.indexOf(dVal[3]) != -1
              ? sections.indexOf(dVal[3])
              : 0,
          ];
      range = { years, months, days, sections };
      year = dVal[0] ? dVal[0] : years[0];
      month = dVal[1] ? dVal[1] : months[0];
      day = dVal[2] ? dVal[2] : days[0];
      section = dVal[3] ? dVal[3] : sections[0];
      result = full = `${year + "-" + month + "-" + day + " " + section}`;
      obj = {
        year,
        month,
        day,
        section,
      };
      this.range = range;
      this.checkObj = obj;
      this.$nextTick(() => {
        this.pickVal = pickVal;
      });
      this.$emit("change", {
        result: result,
        value: full,
        obj: obj,
      });
    },
    handlerChange(e) {
      let arr = [...e.detail.value];
      let data = this.range;
      let year = "",
        month = "",
        day = "",
        section = "";
      let result = "",
        full = "",
        obj = {};
      let months = null,
        days = null,
        sections = null;
      let disabledAfter = this.disabledAfter;
      year =
        arr[0] || arr[0] == 0
          ? data.years[arr[0]] || data.years[data.years.length - 1]
          : "";
      month =
        arr[1] || arr[1] == 0
          ? data.months[arr[1]] || data.months[data.months.length - 1]
          : "";
      day =
        arr[2] || arr[2] == 0
          ? data.days[arr[2]] || data.days[data.days.length - 1]
          : "";
      section =
        arr[3] || arr[3] == 0
          ? data.sections[arr[3]] || data.sections[data.sections.length - 1]
          : "";
      result = full = `${year + "-" + month + "-" + day + " " + section}`;
      let resetData = this.resetData(year, month, day);
      if (this.disabledAfter) {
        months = resetData.months;
        days = resetData.days;
        sections = resetData.sections;
      } else {
        if (year % 4 == 0 || month != this.checkObj.month) {
          days = resetData.days;
        }
      }

      if (this.disabledBefore) {
        let curDate = new Date();
        let curYear = curDate.getFullYear();
        let curMonth = curDate.getMonth() + 1;
        let curMonthdays = new Date(curYear, curMonth, 0).getDate();
        let curDay = curDate.getDate();
        let curHour = curDate.getHours();
        if (
          year === curYear + "" &&
          month * 1 === curMonth &&
          day === curDay + "" &&
          curHour > 12
        ) {
          this.range.sections = ["下午"];
        } else {
          this.range.sections = ["上午", "下午"];
        }
      }

      if (months) this.range.months = months;
      if (days) this.range.days = days;
      if (sections) this.range.sections = sections;
      obj = {
        year,
        month,
        day,
        section,
      };
      this.checkObj = obj;
      this.$emit("change", {
        result: result,
        value: full,
        obj: obj,
      });
    },
  },
};
</script>

<style lang="scss">
@import "./w-picker.css";
</style>