<template>
  <transition name="qf-zoom-in-top" @after-leave="$emit('dodestroy')">
    <div
      v-show="visible"
      class="qf-picker-panel qf-date-range-picker qf-popper"
      :class="[{
        'has-sidebar': $slots.sidebar || shortcuts,
      }, popperClass]">
      <div class="qf-picker-panel__body-wrapper">
        <slot name="sidebar" class="qf-picker-panel__sidebar"></slot>
        <div class="qf-picker-panel__sidebar" v-if="shortcuts">
          <button
            type="button"
            class="qf-picker-panel__shortcut"
            v-for="shortcut in shortcuts"
            @click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
        </div>
        <div class="qf-picker-panel__body">
          <div class="qf-picker-panel__content qf-date-range-picker__content is-left">
            <div class="qf-date-range-picker__header">
              <button
                type="button"
                @click="leftPrevYear"
                class="qf-picker-panel__icon-btn qf-icon-d-arrow-left">
                <qf-font-icon name="ic-ic_shangyinian"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="leftPrevMonth"
                class="qf-picker-panel__icon-btn qf-icon-arrow-left">
                <qf-font-icon name="ic-ic_shangyiyue"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="leftNextYear"
                v-if="unlinkPanels"
                :disabled="!enableYearArrow"
                :class="{ 'is-disabled': !enableYearArrow }"
                class="qf-picker-panel__icon-btn qf-icon-d-arrow-right">
                <qf-font-icon name="ic-ic_xiayinian"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="leftNextMonth"
                v-if="unlinkPanels"
                :disabled="!enableMonthArrow"
                :class="{ 'is-disabled': !enableMonthArrow }"
                class="qf-picker-panel__icon-btn qf-icon-arrow-right">
                <qf-font-icon name="ic-ic_xiayiyue"></qf-font-icon>
              </button>
              <div>{{ leftLabel }}</div>
            </div>
            <date-table
              selection-mode="range"
              :date="leftDate"
              :default-value="defaultValue"
              :min-date="minDate"
              :max-date="maxDate"
              :range-state="rangeState"
              :disabled-date="disabledDate"
              @changerange="handleChangeRange"
              :first-day-of-week="firstDayOfWeek"
              @pick="handleRangePick">
            </date-table>
          </div>
          <div class="qf-picker-panel__content qf-date-range-picker__content is-right">
            <div class="qf-date-range-picker__header">
              <button
                type="button"
                @click="rightPrevYear"
                v-if="unlinkPanels"
                :disabled="!enableYearArrow"
                :class="{ 'is-disabled': !enableYearArrow }"
                class="qf-picker-panel__icon-btn qf-icon-d-arrow-left">
                <qf-font-icon name="ic-ic_shangyinian"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="rightPrevMonth"
                v-if="unlinkPanels"
                :disabled="!enableMonthArrow"
                :class="{ 'is-disabled': !enableMonthArrow }"
                class="qf-picker-panel__icon-btn qf-icon-arrow-left">
                <qf-font-icon name="ic-ic_shangyiyue"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="rightNextYear"
                class="qf-picker-panel__icon-btn qf-icon-d-arrow-right">
                <qf-font-icon name="ic-ic_xiayinian"></qf-font-icon>
              </button>
              <button
                type="button"
                @click="rightNextMonth"
                class="qf-picker-panel__icon-btn qf-icon-arrow-right">
                <qf-font-icon name="ic-ic_xiayiyue"></qf-font-icon>
              </button>
              <div>{{ rightLabel }}</div>
            </div>
            <date-table
              selection-mode="range"
              :date="rightDate"
              :default-value="defaultValue"
              :min-date="minDate"
              :max-date="maxDate"
              :range-state="rangeState"
              :disabled-date="disabledDate"
              @changerange="handleChangeRange"
              :first-day-of-week="firstDayOfWeek"
              @pick="handleRangePick">
            </date-table>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script type="text/babel">
  import DateUtil from '../../util/DateUtil';
  import DateTable from '../base/date-table';
  import LocaleMixin from '../../locale/mixin';
  import QfFontIcon from '../../font-icon';

  const advanceDate = (date, amount) => {
    return new Date(new Date(date).getTime() + amount);
  };
  const calcDefaultValue = (defaultValue) => {
    if (Array.isArray(defaultValue)) {
      return [new Date(defaultValue[0]), new Date(defaultValue[1])];
    } else if (defaultValue) {
      return [new Date(defaultValue), advanceDate(defaultValue, 24 * 60 * 60 * 1000)];
    } else {
      return [new Date(), advanceDate(Date.now(), 24 * 60 * 60 * 1000)];
    }
  };
  export default {
    mixins: [LocaleMixin],
    computed: {
      btnDisabled() {
        return !(this.minDate && this.maxDate && !this.selecting);
      },
      leftLabel() {
        return this.leftDate.getFullYear() + ' ' + this.t('qf.datepicker.year') + ' ' + this.t(`qf.datepicker.month${this.leftDate.getMonth() + 1}`);
      },
      rightLabel() {
        return this.rightDate.getFullYear() + ' ' + this.t('qf.datepicker.year') + ' ' + this.t(`qf.datepicker.month${this.rightDate.getMonth() + 1}`);
      },
      leftYear() {
        return this.leftDate.getFullYear();
      },
      leftMonth() {
        return this.leftDate.getMonth();
      },
      rightYear() {
        return this.rightDate.getFullYear();
      },
      rightMonth() {
        return this.rightDate.getMonth();
      },
      dateFormat() {
        if (this.format) {
          return this.format.replace('HH:mm', '').replace(':ss', '').trim();
        } else {
          return 'yyyy-MM-dd';
        }
      },
      enableMonthArrow() {
        const nextMonth = (this.leftMonth + 1) % 12;
        const yearOffset = this.leftMonth + 1 >= 12 ? 1 : 0;
        return this.unlinkPanels && new Date(this.leftYear + yearOffset, nextMonth) < new Date(this.rightYear, this.rightMonth);
      },
      enableYearArrow() {
        return this.unlinkPanels && this.rightYear * 12 + this.rightMonth - (this.leftYear * 12 + this.leftMonth + 1) >= 12;
      }
    },
    data() {
      return {
        popperClass: '',
        value: [],
        defaultValue: null,
        minDate: '',
        maxDate: '',
        leftDate: new Date(),
        rightDate: DateUtil.nextMonth(new Date()),
        rangeState: {
          endDate: null,
          selecting: false,
          row: null,
          column: null
        },
        shortcuts: '',
        visible: '',
        disabledDate: '',
        firstDayOfWeek: 7,
        format: '',
        arrowControl: false,
        unlinkPanels: false
      };
    },
    watch: {
      value(newVal) {
        if (!newVal) {
          this.minDate = null;
          this.maxDate = null;
        } else if (Array.isArray(newVal)) {
          this.minDate = DateUtil.isDate(newVal[0]) ? new Date(newVal[0]) : null;
          this.maxDate = DateUtil.isDate(newVal[1]) ? new Date(newVal[1]) : null;
          // NOTE: currently, maxDate = minDate + 1 month
          //       should allow them to be set individually in the future
          if (this.minDate) {
            this.leftDate = this.minDate;
            if (this.unlinkPanels && this.maxDate) {
              const minDateYear = this.minDate.getFullYear();
              const minDateMonth = this.minDate.getMonth();
              const maxDateYear = this.maxDate.getFullYear();
              const maxDateMonth = this.maxDate.getMonth();
              this.rightDate = minDateYear === maxDateYear && minDateMonth === maxDateMonth
                ? DateUtil.nextMonth(this.maxDate)
                : this.maxDate;
            } else {
              this.rightDate = DateUtil.nextMonth(this.leftDate);
            }
          } else {
            this.leftDate = calcDefaultValue(this.defaultValue)[0];
            this.rightDate = DateUtil.nextMonth(this.leftDate);
          }
        }
      },
      defaultValue(val) {
        if (!Array.isArray(this.value)) {
          const [left, right] = calcDefaultValue(val);
          this.leftDate = left;
          this.rightDate = val && val[1] && this.unlinkPanels
            ? right
            : DateUtil.nextMonth(this.leftDate);
        }
      }
    },
    methods: {
      handleChangeRange(val) {
        this.minDate = val.minDate;
        this.maxDate = val.maxDate;
        this.rangeState = val.rangeState;
      },
      handleRangePick(val, close = true) {
        const minDate = val.minDate;
        const maxDate = val.maxDate;
        if (this.maxDate === maxDate && this.minDate === minDate) {
          return;
        }
        this.onPick && this.onPick(val);
        this.maxDate = maxDate;
        this.minDate = minDate;
        // workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
        setTimeout(() => {
          this.maxDate = maxDate;
          this.minDate = minDate;
        }, 10);
        if (!close || this.showTime) return;
        this.handleConfirm();
      },
      handleShortcutClick(shortcut) {
        if (shortcut.onClick) {
          shortcut.onClick(this);
        }
      },
      // leftPrev*, rightNext* need to take care of `unlinkPanels`
      leftPrevYear() {
        this.leftDate = DateUtil.prevYear(this.leftDate);
        if (!this.unlinkPanels) {
          this.rightDate = DateUtil.nextMonth(this.leftDate);
        }
      },
      leftPrevMonth() {
        this.leftDate = DateUtil.prevMonth(this.leftDate);
        if (!this.unlinkPanels) {
          this.rightDate = DateUtil.nextMonth(this.leftDate);
        }
      },
      rightNextYear() {
        if (!this.unlinkPanels) {
          this.leftDate = DateUtil.nextYear(this.leftDate);
          this.rightDate = DateUtil.nextMonth(this.leftDate);
        } else {
          this.rightDate = DateUtil.nextYear(this.rightDate);
        }
      },
      rightNextMonth() {
        if (!this.unlinkPanels) {
          this.leftDate = DateUtil.nextMonth(this.leftDate);
          this.rightDate = DateUtil.nextMonth(this.leftDate);
        } else {
          this.rightDate = DateUtil.nextMonth(this.rightDate);
        }
      },
      // leftNext*, rightPrev* are called when `unlinkPanels` is true
      leftNextYear() {
        this.leftDate = DateUtil.nextYear(this.leftDate);
      },
      leftNextMonth() {
        this.leftDate = DateUtil.nextMonth(this.leftDate);
      },
      rightPrevYear() {
        this.rightDate = DateUtil.prevYear(this.rightDate);
      },
      rightPrevMonth() {
        this.rightDate = DateUtil.prevMonth(this.rightDate);
      },
      handleConfirm(visible = false) {
        this.$emit('pick', [this.minDate, this.maxDate], visible);
      },
      isValidValue(value) {
        return Array.isArray(value) &&
          value && value[0] && value[1] &&
          DateUtil.isDate(value[0]) && DateUtil.isDate(value[1]) &&
          value[0].getTime() <= value[1].getTime() && (
          typeof this.disabledDate === 'function'
            ? !this.disabledDate(value[0]) && !this.disabledDate(value[1])
            : true
        );
      }
    },
    components: { DateTable, QfFontIcon }
  };
</script>
