<template>
  <div :class="prefixCls">
    <div :class="[prefixCls + '-header']">
      <span @click="changeYear(-1)"
        ><Icon type="ios-arrow-dropleft"></Icon
      ></span>
      <span @click="changMonth(-1)"><Icon type="ios-arrow-back"></Icon></span>
      <span @click="changeYear(1)"
        ><Icon type="ios-arrow-dropright"></Icon
      ></span>
      <span @click="changMonth(1)"><Icon type="ios-arrow-forward"></Icon></span>
      <div :class="[prefixCls + '-title']">{{ headerTitle }}</div>
    </div>
    <div :class="[prefixCls + '-cells']">
      <div :class="[prefixCls + '-cells-header']">
        <span
          v-for="(item, index) in headerDays"
          :class="[prefixCls + '-cell']"
          :key="index"
          ><em>{{ item }}</em></span
        >
      </div>
      <div :class="[prefixCls + '-cells-body']">
        <span
          v-for="(cell, index) in cells"
          :key="index"
          :class="getCellCls(cell)"
          @click="handleClick(cell)"
        >
          <em>{{ cell.desc }}</em>
        </span>
      </div>
    </div>
  </div>
</template>

<script>
import jsCalendar from "js-calendar";

const prefixCls = "ivu-calendar-memo";
const weekDays = ["一", "二", "三", "四", "五", "六", "日"];

const clearHours = function(time) {
  const cloneDate = new Date(time);
  cloneDate.setHours(0, 0, 0, 0);
  return cloneDate.getTime();
};

export default {
  name: "calendar-memo",
  props: {
    weekStartDay: {
      type: [Number, String],
      default: 1,
      validator(val) {
        return [0, 1].indexOf(parseInt(val)) > -1;
      }
    },
    disabledDates: {
      type: Array,
      default() {
        return [];
      }
    },
    memoDates: {
      type: Array,
      default() {
        return [];
      }
    },
    onDateClick: {
      type: Function,
      default() {
        return {};
      }
    }
  },
  data() {
    return {
      prefixCls: prefixCls,
      curDate: {
        year: "",
        month: ""
      }
    };
  },
  mounted() {
    let date = new Date();
    this.curDate = {
      year: date.getFullYear(),
      month: date.getMonth()
    };
  },
  computed: {
    headerTitle() {
      return `${this.curDate.year} 年 ${this.curDate.month + 1} 月`;
    },
    headerDays() {
      let translatedDays = [...weekDays];
      if (!this.weekStartDay) {
        let last = translatedDays.pop();
        translatedDays.unshift(last);
      }
      return translatedDays;
    },
    calendar() {
      return new jsCalendar.Generator({
        onlyDays: true,
        weekStart: parseInt(this.weekStartDay)
      });
    },
    cells() {
      const today = clearHours(new Date());
      return this.calendar(this.curDate.year, this.curDate.month, cell => {
        const time = cell.date && clearHours(cell.date);
        return {
          ...cell,
          type: time === today ? "today" : cell.type,
          actived: this.checkActived(cell.date),
          disabled: this.checkDisabled(cell.date)
        };
      }).cells;
    }
  },
  methods: {
    getCellCls(cell) {
      return [
        `${prefixCls}-cell`,
        {
          [`${prefixCls}-cell-actived`]: cell.actived,
          [`${prefixCls}-cell-disabled`]: cell.disabled,
          [`${prefixCls}-cell-today`]: cell.type === "today",
          [`${prefixCls}-cell-prev-month`]: cell.type === "prevMonth",
          [`${prefixCls}-cell-next-month`]: cell.type === "nextMonth"
        }
      ];
    },
    checkDisabled(time) {
      if (!time) return false;
      if (!this.disabledDates.length) return false;
      let temp = time.getTime();
      return this.disabledDates.some(item => {
        return new Date(item).getTime() === temp;
      });
    },
    checkActived(time) {
      if (!time) return false;
      if (!this.memoDates.length) return false;
      let temp = time.getTime();
      return this.memoDates.some(item => {
        return new Date(item).getTime() === temp;
      });
    },
    changeYear(dir) {
      this.curDate.year = this.curDate.year + dir;
    },
    changMonth(dir) {
      let month = dir + this.curDate.month;
      if (month > 11) {
        this.curDate.year = this.curDate.year + 1;
        this.curDate.month = month - 11;
      } else if (month < 0) {
        this.curDate.year = this.curDate.year - 1;
        this.curDate.month = month + 11;
      } else {
        this.curDate.month = month;
      }
    },
    handleClick(date) {
      if (date.disabled) return;
      this.onDateClick(date);
    }
  }
};
</script>

<style lang="postcss">
.ivu-calendar-memo {
  min-width: 300px;
  box-shadow: 0 0 1px #d0d0d0;
}
.ivu-calendar-memo-header {
  height: 41px;
  padding: 2px;
  text-align: center;
  border-bottom: 1px solid #e0e0e0;
}
.ivu-calendar-memo-header span {
  display: block;
  float: left;
  width: 36px;
  height: 36px;
  line-height: 32px;
  font-size: 20px;
  color: #c5c8ce;
  border-radius: 5px;
  cursor: pointer;
}
.ivu-calendar-memo-header span:nth-of-type(3),
.ivu-calendar-memo-header span:nth-of-type(4) {
  float: right;
}
.ivu-calendar-memo-header span:hover {
  color: #2d8cf0;
  background: #e1f0fe;
}
.ivu-calendar-memo-title {
  margin: 0 90px;
  height: 36px;
  line-height: 36px;
}
.ivu-calendar-memo-cells {
  padding: 10px;
}
.ivu-calendar-memo-cells-header {
  height: 40px;
  color: #c5c8ce;
}
.ivu-calendar-memo-cells-body {
  overflow: hidden;
}
.ivu-calendar-memo-cell {
  float: left;
  display: block;
  position: relative;
  width: 14.25%;
  height: 40px;
  padding: 2px;
  cursor: pointer;
}
.ivu-calendar-memo-cell:hover em {
  background: #e1f0fe;
}
.ivu-calendar-memo-cell em {
  display: block;
  height: 36px;
  line-height: 34px;
  border: 1px solid transparent;
  text-align: center;
  font-size: 16px;
  border-radius: 5px;
  transition: all 0.2s ease-in-out;
}
.ivu-calendar-memo-cell-actived::after {
  content: "";
  display: block;
  position: absolute;
  border: 5px solid #2d8cf0;
  border-radius: 50%;
  left: 50%;
  top: 50%;
  margin-top: -13px;
  margin-left: 13px;
}
.ivu-calendar-memo-cell-disabled em {
  cursor: not-allowed;
  color: #c5c8ce !important;
  background: #fff !important;
  border-color: transparent !important;
}
.ivu-calendar-memo-cell-today em {
  border-color: #5cadff;
}
.ivu-calendar-memo-cell-prev-month em,
.ivu-calendar-memo-cell-next-month em {
  color: #c5c8ce;
}
</style>
