<template>
  <ul v-bind:class="[componentClass]" v-show="!hideWhenOnePageOnly || pagerPagesCount > 1">
    <li v-if='isDeterminate' class='c-rowsCnt'>{{formatValue(pagerRowsCount, 'numeric')}}</li>
    <li v-if='isDeterminate' class='c-rowsCntLab'>{{labelCount}}</li>
    <li class='c-btn first' v-if="showFirstPageButton" v-bind:class="{'hidden':(pagerPageNo <= 1 )}" @[clickEv]="setPageNoFirst">
      <router-link :to="fpLink" v-if="hasLink" />
    </li>
    <li class='c-btn prev' v-if="showPreviousPageButton" v-bind:class="{'hidden':(pagerPageNo <= 1 )}" @[clickEv]="setPageNoPrev">
      <router-link :to="ppLink" v-if="hasLink" />
      <template v-else>
        {{ppButtonLabel}}
      </template>
    </li>
    <li v-if='isDeterminate'>
      <input class='c-pageNo' type="number" :value="pagerPageNo" v-on:change="onPageChange"/>
    </li>
    <template v-if='!isDeterminate'>
      <li v-if="showFirstPage && pagerPageNo >= buttonsCount"
        :class="{'c-firstPage':true,'paged':!isDeterminate}"
        @[clickEv]="setPageNoFirst"
      >1
        <router-link :to="fpLink" v-if="hasLink" />
      </li>
      <li class='c-btn' v-bind:class="{'hidden':(pagerPageNo < buttonsCount )}" @[clickEv]="setPageNoPrev">...<router-link :to="ppLink" v-if="hasLink" /></li>
      <li v-for="i in buttons" :key="i" v-bind:class="{'paged':true,'active':(pagerPageNo == i)}" @[clickEv]="setPageNo(i)">
        {{i}}
        <router-link :to="buildLink(i)" v-if="hasLink" />
      </li>
      <li class='c-btn' v-bind:class="{'hidden':(pagerPageNo >= pagerPagesCount - Math.floor(buttonsCount / 2) + (1 - buttonsCount % 2) || pagerPagesCount <= buttonsCount)}" @[clickEv]="setPageNoNext">...<router-link :to="npLink" v-if="hasLink" /></li>
    </template>
    <li v-if='isDeterminate' class='c-sep'>{{labelSep}}</li>
    <li v-if='isDeterminate || (showPagesCnt && pagerPageNo < pagerPagesCount - Math.floor(buttonsCount / 2) + (1 - buttonsCount % 2) && pagerPagesCount > buttonsCount)' 
      :class="{'c-pagesCnt':true,'paged':!isDeterminate}"
      @[clickEv]="setPageNoLast"
    >{{pagerPagesCount}}<router-link :to="lpLink" v-if="hasLink" />
    </li>
    <li class='c-btn next' v-if="showNextPageButton" v-bind:class="{'hidden':(pagerPageNo >= pagerPagesCount )}" @[clickEv]="setPageNoNext">
      <router-link :to="npLink" v-if="hasLink" />
      <template v-else>
        {{npButtonLabel}}
      </template>
    </li>
    <li class='c-btn last' v-if="showLastPageButton" v-bind:class="{'hidden':(pagerPageNo >= pagerPagesCount )}" @[clickEv]="setPageNoLast">
      <router-link :to="lpLink" v-if="hasLink" />
    </li>
  </ul>
</template>

<script>
import { mapActions, mapGetters } from 'vuex'
import base from './c-base'
const props = {
  kind: {
    type: String,
    default: null
  },
  btnsCnt: {
    type: Number,
    default: 3
  },
  sourceKind: {
    type: String,
    default: 'rows'
  },
  labelCount: {
    type: String,
    default: 'rekordów'
  },
  showFirstPageButton: {
    type: Boolean,
    default: true
  },
  showLastPageButton: {
    type: Boolean,
    default: true
  },
  showPreviousPageButton: {
    type: Boolean,
    default: true
  },
  showNextPageButton: {
    type: Boolean,
    default: true
  },
  previousPageButtonLabel: {
    type: String
  },
  nextPageButtonLabel: {
    type: String
  },
  showPagesCnt: {
    type: Boolean,
    default: false
  },
  showFirstPage: {
    type: Boolean,
    default: false
  },
  scrollTopOnPageChange: {
    type: Boolean,
    default: true
  },
  hideWhenOnePageOnly: {
    type: Boolean,
    default: false
  },
}

export default {
  extends: base,
  props,
  data: function () {
    return {
      labelSep: 'z',
      componentClass: 'c-pager',
      buttonsCount: Math.floor(this.btnsCnt),
      isDeterminate: this.kind == 'determinate'
    }
  },
  computed: {
    ...mapGetters('csAppWindowsUtils',[
      'getDataSetWhereFieldsIdents'
    ]),
    pagerRowsCount: function() {
      switch (this.sourceKind) { 
        case 'rows': return this.rowsCount;
        case 'pivot-rows': return this.pivotRowsCount;
        case 'pivot-cols': return this.pivotColsCount;
        default: return this.rowsCount;
      }
    },
    pagerPagesCount: function() {
      switch (this.sourceKind) { 
        case 'rows': return this.pagesCount;
        case 'pivot-rows': return this.pivotRowsPagesCount; 
        case 'pivot-cols': return this.pivotColsPagesCount;
        default: return this.pagesCount;
      }
    },
    pagerPageNo: function() {
      switch (this.sourceKind) { 
        case 'rows': return this.pageNo;
        case 'pivot-rows': return this.pivotRowsPageNo;
        case 'pivot-cols': return this.pivotColsPageNo;
        default: return this.pageNo;
      }
    },
    whereFieldIdent: function(){
      let wfis = this.getDataSetWhereFieldsIdents(this.dataSet)
      if (wfis == null)
        return false
      return wfis.find(wfi => wfi.dataSetAttrib === 'pageNo')
    },
    whereFieldIdentDefValue: function(){
      return this.whereFieldIdent != null ? this.whereFieldIdent.dataFieldValueDef : null
    },
    hasLink: function(){
      return this.whereFieldIdent != null && this.whereFieldIdent.linkedParamName != null
    },
    linkedParamName: function(){
      return this.whereFieldIdent.linkedParamName
    },
    npButtonLabel: function(){
      return this.isPhone ? null : this.nextPageButtonLabel
    },
    ppButtonLabel: function(){
      return this.isPhone ? null : this.previousPageButtonLabel
    },
    ppLink: function(){
      return this.buildLink(this.pagerPageNo - 1)
    },
    npLink: function(){
      return this.buildLink(this.pagerPageNo + 1)
    },
    fpLink: function(){
      return this.buildLink(1)
    },
    lpLink: function(){
      return this.buildLink(this.pagerPagesCount)
    },
    buttons: function() {
      let result = []
      let b = this.buttonsCount  > this.pagerPagesCount ? this.pagerPagesCount : this.buttonsCount;
      
      if (this.pagerPageNo < b) {
        for (let i = 1; i <= b; i++) {
          result.push(i)
        }
      } else {
        let start = this.pagerPageNo - Math.floor(b / 2)
        for (let i = start; i <= b + start - 1; i++) {
          if (i > this.pagerPagesCount) {
            break
          }
          result.push(i)
        }
      }
      return result
    },
    clickEv: function(){
      return this.hasLink ? null : 'click'
    }
  },
  methods: {
    ...mapActions('csAppWindowsUtils', [
      'setDataSetPageNo',
      'setDataSetPivotColsPageNo',
      'setDataSetPivotRowsPageNo',
      'setDataSetPageNoFirst',
      'setDataSetPivotColsPageNoFirst',
      'setDataSetPivotRowsPageNoFirst',
      'setDataSetPageNoLast',
      'setDataSetPivotColsPageNoLast',
      'setDataSetPivotRowsPageNoLast',
      'setDataSetPageNoPrev',
      'setDataSetPivotColsPageNoPrev',
      'setDataSetPivotRowsPageNoPrev',
      'setDataSetPageNoNext',
      'setDataSetPivotColsPageNoNext',
      'setDataSetPivotRowsPageNoNext'
    ]),
    buildLink: function(pageNo){
      if (!this.$route)
        return null
      let path = this.$route.path
      let query = {}
      for (const prop in this.$route.query){
        query[prop] = this.$route.query[prop]
      }
      if (pageNo == this.whereFieldIdentDefValue)
        query[this.linkedParamName] = undefined
      else
        query[this.linkedParamName] = pageNo
      return {path, query}
    },
    payloadPageOperation: function (pageNo) {
      return {
        appWindowIdent: this.appWindowIdent,
        dataSet: this.dataSet,
        pageNo: pageNo
      }
    },

    setPageNo: function(pageNo) {
      let payload = this.payloadPageOperation(pageNo)
      switch (this.sourceKind) { 
        case 'rows': this.setDataSetPageNo(payload); break;
        case 'pivot-rows': this.setDataSetPivotRowsPageNo(payload); break;
        case 'pivot-cols': this.setDataSetPivotColsPageNo(payload); break;
        default: this.setDataSetPageNo(payload); break;
      }
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    },
    setPageNoFirst: function() {
      let payload = this.payloadPageOperation()
      switch (this.sourceKind) { 
        case 'rows': this.setDataSetPageNoFirst(payload); break;
        case 'pivot-rows': this.setDataSetPivotRowsPageNoFirst(payload); break;
        case 'pivot-cols': this.setDataSetPivotColsPageNoFirst(payload); break;
        default: this.setDataSetPageNoFirst(payload); break;
      }
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    },
    setPageNoLast: function() {
      let payload = this.payloadPageOperation()
      switch (this.sourceKind) { 
        case 'rows': this.setDataSetPageNoLast(payload); break;
        case 'pivot-rows': this.setDataSetPivotRowsPageNoLast(payload); break;
        case 'pivot-cols': this.setDataSetPivotColsPageNoLast(payload); break;
        default: this.setDataSetPageNoLast(payload); break;
      }
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    },
    setPageNoPrev: function() {
      let payload = this.payloadPageOperation()
      switch (this.sourceKind) { 
        case 'rows': this.setDataSetPageNoPrev(payload); break;
        case 'pivot-rows': this.setDataSetPivotRowsPageNoPrev(payload); break;
        case 'pivot-cols': this.setDataSetPivotColsPageNoPrev(payload); break;
        default: this.setDataSetPageNoPrev(payload); break;
      }
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    },
    setPageNoNext: function() {
      let payload = this.payloadPageOperation()
      switch (this.sourceKind) { 
        case 'rows': this.setDataSetPageNoNext(payload); break;
        case 'pivot-rows': this.setDataSetPivotRowsPageNoNext(payload); break;
        case 'pivot-cols': this.setDataSetPivotColsPageNoNext(payload); break;
        default: this.setDataSetPageNoNext(payload); break;
      }
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    },
    onPageChange: function(evt) {
      this.setPageNo(evt.target.valueAsNumber)
      if(this.scrollTopOnPageChange) {
        window.scrollTo(0, 0)
      }
    }
  },
}</script>
