<template>
    <div :class="['table__wrapper', { classicTable: classicTable }]">
        <div class="table__pagination">
            <Pagination v-model="currentPage" :totalPages="totalPages"></Pagination>
            <PerPageSelector :perPagesText="perPagesText" v-model="perPage"></PerPageSelector>
        </div>
        <TableComponent :data="items"
                        show-filter
                        show-caption
                        :reorderable="reorderable"
                        @dragEnd="changeOrder"
                        :filter-no-results="filterNoResults"
                        ref="tableComponent"
        >
            <slot></slot>
        </TableComponent>
        <div class="table__pagination bottom">
            <div class="table__bottomButton">
                <slot name="button"></slot>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
    import {TableComponent} from 'vue-table-component';
    import PerPageSelector from '../tables/PerPageSelector.vue';
    import Pagination from '../tables/Pagination.vue';
    import type {PaginatedListApiResponse} from "../../types/PaginatedListApiResponse";
    import Vue from "vue";

    export type DragEndPayload = {
        new: number,
        old: number,
    };

    export type ChangeOrderPayload = {
        order: DragEndPayload,
        item: any,
    };

    const DEFAULT_PAGE = 1;

    export default Vue.extend({
        components: {
            TableComponent,
            PerPageSelector,
            Pagination,
        },
        props: {
            loadItemsFunction: {
                type: Function,
                required: true,
            },
            classicTable: {
                type: Boolean,
                default: false,
            },
            filterNoResults: {
                type: String,
                default: 'no result',
            },
            reorderable: {
                type: Boolean,
                default: false,
            },
            perPagesText: String,
        },
        data() {
            return {
                items: [] as any[],
                totalPages: 0,
                currentPage: DEFAULT_PAGE,
                perPage: 10,
            };
        },
        watch: {
            currentPage() {
                this._loadData();
            },
            perPage() {
                this.currentPage = DEFAULT_PAGE;
                this._loadData();
            },
        },
        methods: {
            _loadData(): Promise<void> {
                return this.loadItemsFunction(this.currentPage, this.perPage)
                    .then((response: PaginatedListApiResponse) => {
                        this.items = response.data.data;
                        this.totalPages = response.data.meta.last_page;
                    })
                    .catch((e) => {
                        console.error(e);
                    });
            },
            reloadFromFirstPage(): Promise<void> {
                this.currentPage = 1;
                return this._loadData();
            },
            changeOrder(order: DragEndPayload): void {
                this.$emit('changeOrder', {
                    order: order,
                    item: this.items[order.old],
                });
            },
        },
        created() {
            this._loadData();
        },
    });
</script>

<style scoped lang="scss">
    @import "tableWrapper";
</style>
