<template>
  <div class="m-pagination my-3">
    <m-pagination-button
      :disabled="isPreviousButtonDisabled"
      title="Página anterior"
      @click.native="previousPage">
      ←
    </m-pagination-button>

    <m-pagination-trigger
      v-for="paginationTrigger in paginationTriggers"
      :key="paginationTrigger"
      :class="{
        'm-pagination__page--current':
          paginationTrigger === currentPage
      }"
      :page-number="paginationTrigger"
      :title="`Ir a la página ${paginationTrigger}`"
      class="m-pagination__page"
      @loadPage="onLoadPage" />

    <m-pagination-button
      :disabled="isNextButtonDisabled"
      title="Página siguiente"
      @click.native="nextPage">
      →
    </m-pagination-button>
  </div>
</template>

<script>

import MPaginationButton from './components/MPaginationButton.vue';
import MPaginationTrigger from './components/MPaginationTrigger.vue';

/**
 * A paginator to setup with vue props.
 */
export default {
  components: {
    MPaginationButton,
    MPaginationTrigger,
  },

  props: {
    // This is used to manipulate the pagination
    currentPage: {
      type: Number,
      required: true,
    },
    // This is the total number of pages
    pageCount: {
      type: Number,
      default: 5,
    },
    // This is how many items we want to see on a single page
    offset: {
      type: Number,
      default: 5,
    },
    // Creates an array with the required length
    visiblePagesCount: {
      type: Number,
      default: 5,
    },
  },

  computed: {
    isPreviousButtonDisabled() {
      return this.currentPage === 1;
    },

    isNextButtonDisabled() {
      return this.currentPage === this.pageCount;
    },

    paginationTriggers() {
      const { currentPage } = this;
      const { pageCount } = this;
      // Creates an array with the required length
      const { visiblePagesCount } = this;
      // Tells us how many pages from the centre
      const visiblePagesThreshold = (visiblePagesCount - 1) / 2;
      // Array that will be filled with page numbers
      const paginationTriggersArray = Array(this.visiblePagesCount - 1).fill(0);

      /* CASE: The selected page number is smaller than half
      of the list width (e.g. 1 – 2 – 3 – 4 – 18) */
      if (currentPage <= visiblePagesThreshold + 1) {
        paginationTriggersArray[0] = 1;
        const paginationTriggers = paginationTriggersArray.map(
          (paginationTrigger, index) => paginationTriggersArray[0] + index,
        );

        paginationTriggers.push(pageCount);

        return paginationTriggers;
      }

      /* CASE: The selected page number is bigger than half of the list
      width counting from the end of the list (e.g. 1 – 15 – 16 – 17 – 18) */
      if (currentPage >= pageCount - visiblePagesThreshold + 1) {
        const paginationTriggers = paginationTriggersArray.map(
          (paginationTrigger, index) => pageCount - index,
        );

        paginationTriggers.reverse().unshift(1);

        return paginationTriggers;
      }

      /* All other cases (e.g. 1 – 4 – 5 – 6 – 18) */
      paginationTriggersArray[0] = currentPage - visiblePagesThreshold + 1;
      const paginationTriggers = paginationTriggersArray.map(
        (paginationTrigger, index) => paginationTriggersArray[0] + index,
      );

      paginationTriggers.unshift(1);
      paginationTriggers[paginationTriggers.length - 1] = pageCount;

      return paginationTriggers;
    },
  },

  methods: {
    nextPage() {
      this.$emit('nextPage');
    },

    onLoadPage(value) {
      this.$emit('loadPage', value);
    },

    previousPage() {
      this.$emit('previousPage');
    },
  },
};

</script>

<style lang="scss" scoped>
$primary: #828b8e;
$primary-accent: #2e4553;

.m-pagination {
  display: flex;

  align-items: center;

  justify-content: center;

  &__page {
    display: flex;

    margin: 0 17px;

    font-size: 16px;
    color: $primary;

    &--current {
      font-weight: 700;
      color: $primary-accent;
    }
  }
}
</style>
