<template>
    <div class="d-flex justify-content-between mt-4">
        <div class="d-flex flex-column justify-content-end">
            <select
                v-if="mode === 'records' || allowPerPageSelect && mode === 'offset'"
                aria-label="select records per page"
                v-model="currentPerPage"
                autocomplete="off"
                name="perPageSelect"
                class="form-control"
                @change="perPageChanged">
                <option
                    v-for="(option, idx) in rowsPerPageOptions"
                    :key="'rows-dropdown-option-' + idx"
                    :value="option">
                    {{ option + ' per page' }}
                </option>
                <option
                    v-if="paginateDropdownAllowAll"
                    :value="total">
                    {{ allText }}
                </option>
            </select>
        </div>

        <transition name="fade">
            <TaPagination
                v-if="(total > currentPerPage) && mode === 'records'"
                :current-page="currentPage"
                :records-per-page="currentPerPage"
                :count="total"
                :count-loading="countLoading"
                @change="changePage">
            </TaPagination>

            <TaPagination
                v-if="mode === 'offset'"
                :current-page="meta.current_page"
                :records-per-page="meta.per_page"
                :count="meta.total"
                :count-loading="countLoading"
                @change="changePage">
            </TaPagination>

            <CursorPagination
                v-if="mode === 'cursor' && meta.cursor"
                :records-per-page="currentPerPage"
                :next-page-cursor="meta.cursor.next"
                :previous-page-cursor="meta.cursor.prev"
                @page-change="changePage">
            </CursorPagination>
        </transition>
    </div>
</template>

<script>
import _ from 'lodash'
import TaPagination from './TaPagination.vue';
import CursorPagination from './CursorPagination.vue';

const DEFAULT_ROWS_PER_PAGE_DROPDOWN = [ 10, 20, 30, 40, 50 ];

export default {
    name: 'VgtPagination',

    components: {
        TaPagination,
        CursorPagination,
    },
    props: {
        styleClass: { default: 'table table-bordered' },
        total: { default: null },
        perPage: {},
        rtl: { default: false },
        customRowsPerPageDropdown: { default() { return []; } },
        paginateDropdownAllowAll: { default: true },
        mode: { default: 'records' },

        // text options
        nextText: { default: 'Next' },
        prevText: { default: 'Prev' },
        rowsPerPageText: { default: 'Rows per page:' },
        ofText: { default: 'of' },
        pageText: { default: 'page' },
        allText: { default: 'All' },
        meta: { required: false },

        allowPerPageSelect: { default: false },
        countLoading: { default: false },
    },

    data: () => ({
        currentPage: 1,
        prevPage: 0,
        currentPerPage: 10,
        rowsPerPageOptions: [],
    }),

    computed: {
        // Number of pages
        pagesCount() {
            const quotient = Math.floor(this.total / this.currentPerPage);
            const remainder = this.total % this.currentPerPage;

            return remainder === 0 ? quotient : quotient + 1;
        },

        // Current displayed items
        paginatedInfo() {
            let first = ((this.currentPage - 1) * this.currentPerPage) + 1;
            const last = Math.min(this.total, this.currentPage * this.currentPerPage);

            if (last === 0) {
                first = 0;
            }

            return `${first} - ${last} ${this.ofText} ${this.total}`;
        },
    },

    watch: {
        perPage: {
            handler(newValue, oldValue) {
                this.handlePerPage();
                this.perPageChanged(oldValue);
            },
            immediate: true,
        },

        customRowsPerPageDropdown() {
            this.handlePerPage();
        },
    },

    methods: {
        // Change current page
        changePage(pageNumber, emit = true) {
            if (this.mode === 'records') {
                if (pageNumber > 0 && this.total > this.currentPerPage * (pageNumber - 1)) {
                    this.prevPage = this.currentPage;
                    this.currentPage = pageNumber;
                    if (emit) this.pageChanged();
                }
            } else if (emit && [ 'cursor', 'offset' ].includes(this.mode)) {
                this.$emit('page-changed', pageNumber)
            }
        },

        // Indicate page changing
        pageChanged() {
            this.$emit('page-changed', {
                currentPage: this.currentPage,
                prevPage: this.prevPage,
            });
        },

        // Indicate per page changing
        perPageChanged(oldValue) {
            // go back to first page
            if (oldValue) {
                //* only emit if this isn't first initialization
                this.$emit('per-page-changed', { currentPerPage: this.currentPerPage });
            }
            this.changePage(1, false);
        },

        // Handle per page changing
        handlePerPage() {
            //* if there's a custom dropdown then we use that
            if (this.customRowsPerPageDropdown !== null
                && (Array.isArray(this.customRowsPerPageDropdown)
                    && this.customRowsPerPageDropdown.length !== 0)) {
                this.rowsPerPageOptions = this.customRowsPerPageDropdown;
            } else {
                //* otherwise we use the default rows per page dropdown
                this.rowsPerPageOptions = _.cloneDeep(DEFAULT_ROWS_PER_PAGE_DROPDOWN);
            }

            if (this.perPage) {
                this.currentPerPage = this.perPage;
                // if perPage doesn't already exist, we add it
                let found = false;
                for (let i = 0; i < this.rowsPerPageOptions.length; i++) {
                    if (this.rowsPerPageOptions[i] === this.perPage) {
                        found = true;
                    }
                }
                if (!found && this.perPage !== -1) {
                    this.rowsPerPageOptions.unshift(this.perPage);
                }
            } else {
                // reset to default
                this.currentPerPage = 10;
            }
        },
    },
};
</script>

<style lang="scss">

</style>
