<template>
  <div class="qf-pagination">
    <template v-if="total > 0">
      <span class="qf-pagination-total" v-if="type !== 'simple'">
        <span>{{ t('qf.pagination.total', [total]) }}</span>
        <span>{{ t('qf.pagination.no') }} {{internalCurrentPage}} / {{internalPageCount}} {{ t('qf.pagination.pageClassifier') }}</span>
      </span>
      <span class="qf-pagination-total" v-if="type === 'simple'"><span
        class="qf-pagination-current">{{internalCurrentPage}}</span>/<span>{{internalPageCount}}</span></span>
    </template>
    <span class="qf-pagination-total" v-else>{{ t('qf.pagination.noData') }}</span>

    <div>
      <button
        type="button"
        :class="['btn-prev', {disabled: internalCurrentPage <= 1}]"
        @click="onPrev">
        <i class="iconfont ic-ic_shangyiyue"></i>
      </button>
      <ul class="qf-pager" @click="onPagerClick" v-if="type !== 'simple'">
        <li
          :class="{ active: internalCurrentPage === 1 }"
          v-if="internalPageCount > 0"
          class="number">1
        </li>
        <li
          class="iconfont more btn-quickprev"
          :class="[quickPrevIconClass]"
          v-if="showPrevMore"
          @mouseenter="quickPrevIconClass = 'ic-ic_shangyinian'"
          @mouseleave="quickPrevIconClass = 'ic-ic_gengduo'">
        </li>
        <li
          v-for="pager in pagers"
          :key="pager"
          :class="{ active: internalCurrentPage === pager }"
          class="number">{{ pager }}
        </li>
        <li
          class="iconfont more btn-quicknext"
          :class="[quickNextIconClass]"
          v-if="showNextMore"
          @mouseenter="quickNextIconClass = 'ic-ic_xiayinian'"
          @mouseleave="quickNextIconClass = 'ic-ic_gengduo'">
        </li>
        <li
          :class="{ active: internalCurrentPage === internalPageCount }"
          class="number"
          v-if="internalPageCount > 1">{{ internalPageCount }}
        </li>
      </ul>
      <button
        type="button"
        :class="['btn-next', {disabled: internalCurrentPage === internalPageCount || internalPageCount === 0}]"
        @click="onNext">
        <i class="iconfont ic-ic_xiayiyue"></i>
      </button>
      <qf-select v-if="type !== 'simple'" :placement="'top-start'" v-model="internalPageSize" class="qf-pagination-size" @input="onPageSizeChange">
        <qf-option :label="t('qf.pagination.option', [10])" :value="10"></qf-option>
        <qf-option :label="t('qf.pagination.option', [20])" :value="20"></qf-option>
        <qf-option :label="t('qf.pagination.option', [50])" :value="50"></qf-option>
        <qf-option :label="t('qf.pagination.option', [100])" :value="100"></qf-option>
      </qf-select>
    </div>
  </div>
</template>

<script type="text/babel">
import local from '../../locale/mixin';
import KeydownMgr from '../../util/KeydownMgr';

export default {
  name: 'QfPagination',
  mixins: [local],
  props: {
    value: Number,
    total: Number,
    type: String,
    pageSize: {
      type: Number,
      default: 10
    }
  },
  data() {
    return {
      current: null,
      showPrevMore: false,
      showNextMore: false,
      quickNextIconClass: 'ic-ic_gengduo',
      quickPrevIconClass: 'ic-ic_gengduo',
      internalCurrentPage: 1,
      internalPageSize: this.pageSize,
      internalGotoPage: ''
    };
  },
  watch: {
    showPrevMore(val) {
      if (!val) this.quickPrevIconClass = 'ic-ic_gengduo';
    },
    showNextMore(val) {
      if (!val) this.quickNextIconClass = 'ic-ic_gengduo';
    },
    value: {
      immediate: true,
      handler(val) {
        this.internalCurrentPage = this.getValidCurrentPage(val);
      }
    },
    pageSize: {
      immediate: true,
      handler(val) {
        this.internalPageSize = val;
      }
    },
    internalCurrentPage(val) {
      this.$emit('input', val);
      let start = (val - 1) * this.internalPageSize;
      this.$emit('change', start, this.internalPageSize);
    }
  },
  methods: {
    handleCurrentChange(val) {
      this.internalCurrentPage = this.getValidCurrentPage(val);
    },

    getValidCurrentPage(value) {
      value = parseInt(value, 10);

      const havePageCount = typeof this.internalPageCount === 'number';

      let resetValue;
      if (!havePageCount) {
        if (isNaN(value) || value < 1) resetValue = 1;
      } else {
        if (value < 1) {
          resetValue = 1;
        } else if (value > this.internalPageCount) {
          resetValue = this.internalPageCount;
        }
      }

      if (resetValue === undefined && isNaN(value)) {
        resetValue = 1;
      } else if (resetValue === 0) {
        resetValue = 1;
      }

      return resetValue === undefined ? value : resetValue;
    },

    onPagerClick(event) {
      const target = event.target;
      if (target.tagName === 'UL') {
        return;
      }
      let newPage = Number(event.target.textContent);
      const pageCount = this.internalPageCount;
      const currentPage = this.internalCurrentPage;
      if (target.className.indexOf('more') !== -1) {
        if (target.className.indexOf('quickprev') !== -1) {
          newPage = currentPage - 5;
        } else if (target.className.indexOf('quicknext') !== -1) {
          newPage = currentPage + 5;
        }
      }
      if (!isNaN(newPage)) {
        if (newPage < 1) {
          newPage = 1;
        }
        if (newPage > pageCount) {
          newPage = pageCount;
        }
      }
      if (newPage !== currentPage) {
        this.handleCurrentChange(newPage);
      }
    },

    onPrev() {
      const newVal = this.internalCurrentPage - 1;
      this.internalCurrentPage = this.getValidCurrentPage(newVal);
    },

    onNext() {
      const newVal = this.internalCurrentPage + 1;
      this.internalCurrentPage = this.getValidCurrentPage(newVal);
    },

    onPageSizeChange() {
      if (this.internalCurrentPage === 1) {
        let start = (this.internalCurrentPage - 1) * this.internalPageSize;
        this.$emit('change', start, this.internalPageSize);
      } else {
        this.internalCurrentPage = this.getValidCurrentPage(1);
      }
    },

    onGotoPage() {
      let page = parseInt(this.internalGotoPage);
      if (!isNaN(page)) {
        this.internalCurrentPage = this.getValidCurrentPage(page);
      }
    },

    onKeydown(ev) {
      if (this.type === 'simple') {
        // 左键
        if (ev.keyCode === 37) {
          event.stopPropagation();
          event.preventDefault();
          this.onPrev();
        }
        // 右键
        if (ev.keyCode === 39) {
          event.stopPropagation();
          event.preventDefault();
          this.onNext();
        }
      }
    }
  },
  computed: {
    pagers() {
      const pagerCount = 7;
      const currentPage = Number(this.internalCurrentPage);
      const pageCount = Number(this.internalPageCount);
      let showPrevMore = false;
      let showNextMore = false;
      if (pageCount > pagerCount) {
        if (currentPage > pagerCount - 3) {
          showPrevMore = true;
        }
        if (currentPage < pageCount - 3) {
          showNextMore = true;
        }
      }
      const array = [];
      if (showPrevMore && !showNextMore) {
        const startPage = pageCount - (pagerCount - 2);
        for (let i = startPage; i < pageCount; i++) {
          array.push(i);
        }
      } else if (!showPrevMore && showNextMore) {
        for (let i = 2; i < pagerCount; i++) {
          array.push(i);
        }
      } else if (showPrevMore && showNextMore) {
        const offset = Math.floor(pagerCount / 2) - 1;
        for (let i = currentPage - offset; i <= currentPage + offset; i++) {
          array.push(i);
        }
      } else {
        for (let i = 2; i < pageCount; i++) {
          array.push(i);
        }
      }
      this.showPrevMore = showPrevMore;
      this.showNextMore = showNextMore;
      return array;
    },
    internalPageCount() {
      if (typeof this.total === 'number') {
        return Math.ceil(this.total / this.internalPageSize);
      } else if (typeof this.pageCount === 'number') {
        return this.pageCount;
      }
      return null;
    }
  },
  mounted() {
    KeydownMgr.bind(this, this.onKeydown);
  },
  beforeDestroy() {
    KeydownMgr.unbind(this, this.onKeydown);
  }
};
</script>
