<template>
    <div class="data-table">

        <!-- DataManager Header -->
        <div class="data-table-header flex flex-wrap items-center mb-8">
            <div class="w-full mb-2 order-1 lg:mb-0 md:w-1/2 md:pr-1 lg:p-0 lg:w-auto">
                <data-table-per-page @perPageChanged="perPageChanged"></data-table-per-page>
            </div>
            <div class="w-full mb-2 order-2 lg:mb-0 md:w-1/2 md:pl-1 lg:p-0 lg:w-auto lg:order-3">
                <data-table-search @searchChanged="searchChanged"></data-table-search>
            </div>
            <div class="w-full order-3 flex flex-wrap lg:justify-center lg:w-auto lg:flex-1 lg:order-2">
                <slot name="custom-filters" :updateFilters="updateFilters" :getFilterValue="getFilterValue"></slot>
            </div>
        </div>

        <!-- DataManager Has Items -->
        <div v-if="items && items.length" :class="['has-items', state]">

            <!-- DataManager Body -->
            <div class="data-table-body">

                <!-- Slot to pass template through e.g <data-table v-slot="{items}">Your Html Here</data-table> -->
                <slot :items="items"
                      :itemIndex="itemIndex"
                      :isSelected="isSelected"
                      :setAsSelectedItem="setAsSelectedItem"
                      :viewUrl="viewUrl"
                      :editUrl="editUrl"
                      :duplicateUrl="duplicateUrl"
                      :deleteUrl="deleteUrl"
                      :builderUrl="builderUrl"
                >

                    <!-- Fallback template for displaying the list item data  -->
                    <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-3">

                        <v-card
                            v-for="(item, index) in items"
                            :key="item.id"
                            :id="itemIndex(item, index)"
                            :class="['col-span-1', { selected : isSelected(item, index) }]"
                            @click="setAsSelectedItem(item, index)"
                        >
                            <template slot="left">
                                <a :href="viewUrl(item)"
                                   title="View"
                                   class="block font-semibold hover:text-primary-500 focus:text-primary-600"
                                >
                                    {{ item.name }}
                                </a>
                                <div v-if="item.status"
                                     :class="['text-sm', item.status === 'active' ? 'text-green-400' : 'text-red-500']"
                                >
                                    {{ item.status | ucwords }}
                                </div>
                            </template>

                            <template slot="right">
                                <v-button :link="viewUrl(item)">View</v-button>
                                <v-button :link="editUrl(item)">Edit</v-button>
                            </template>
                        </v-card>

                    </div>

                </slot>
            </div>

            <!-- DataManager Footer -->
            <div class="data-table-footer flex flex-wrap items-center mt-8">
                <div class="w-full mb-2 lg:mb-0 lg:w-auto">
                    <data-table-count
                        :totalItems="totalItems"
                        :currentPage="currentPage"
                        :perPage="perPage"
                    >
                    </data-table-count>
                </div>
                <div class="w-full lg:flex lg:justify-end lg:w-auto lg:flex-1" v-if="numberOfPages > 1">
                    <data-table-pagination
                        :totalPage="numberOfPages"
                        @paginationChanged="paginationChanged"
                    >
                    </data-table-pagination>
                </div>
            </div>
        </div>

        <!-- DataManager No Items -->
        <div v-else :class="['no-items', state]">
            <v-card>
                <div class="message text-center">
                    <div class="message-text font-semibold">
                        {{ message }}
                    </div>
                    <div v-if="state === 'no-results'" class="list-reset">
                        <button
                            class="mt-4 inline-flex items-center px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-gray-700 bg-white hover:text-gray-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-gray-800 active:bg-gray-50 transition ease-in-out duration-150"
                            @click="resetSearchQuery"
                        >
                            Reset Filters
                        </button>
                    </div>
                </div>
            </v-card>
        </div>

    </div>
</template>


<script>
import DataTableCount from "./DataTableCount";
import DataTablePagination from "./DataTablePagination";
import DataTablePerPage from "./DataTablePerPage";
import DataTableSearch from "./DataTableSearch";

export default {
    components : {
        DataTableCount,
        DataTablePagination,
        DataTablePerPage,
        DataTableSearch
    },
    props : {
        orderBy : {
            default : 'id',
        },
        orderDirection : {
            default : 'desc',
        },
        searchUrl : {
            required : true
        },
        resourceUrl : {
            required : true
        },

        viewLink : {
            required : false
        },
        editLink : {
            required : false
        },
        duplicateLink : {
            required : false
        },
        deleteLink : {
            required : false
        },
        builderLink : {
            required : false
        },
    },
    computed : {
        numberOfPages() {
            return Math.ceil(this.totalItems / this.perPage);
        }
    },
    data() {
        return {
            items : [],
            filters : [],
            selectedItem : null,
            totalItems : null,
            currentPage : 1,
            perPage : 21,
            searchQuery : null,
            message : 'Loading please wait...',
            state : 'loading'
        }
    },
    methods : {
        getItems() {
            window.axios.get(this.searchUrl, {params : this.getParams()})
                .then((response) => {
                    // Set the items and the total number of results
                    this.items = response.data.results;
                    this.totalItems = response.data.totalResults;
                    this.state = 'done';

                    // Was this a search or does the user just not have any tasks for this status
                    if (!this.items.length && this.searchQuery) {
                        this.state = 'no-results';
                        this.message = 'No results found for "' + this.searchQuery + '"';

                    } else {
                        if (!this.items.length) {
                            this.state = 'success';
                            this.message = 'No Items Found';
                        }
                    }
                })
                .catch(e => {
                    this.state = 'error';
                    this.message = e.message;
                });
        },
        getParams() {
            let params = {
                search : this.searchQuery,
                order_by : this.orderBy,
                order_direction : this.orderDirection,
                length : this.perPage,
                start : (this.perPage * (this.currentPage - 1))
            };
            this.filters.map(function (item) {
                params[item.name] = item.value;
            });

            return params;
        },
        updateFilters(event, key) {
            const filterIndex = this.filters.findIndex((e) => e.name === key);
            if (filterIndex !== -1) {
                this.$set(this.filters, filterIndex, {
                    name : key,
                    value : event.target.value
                });
            } else {
                this.filters.push({
                    name : key,
                    value : event.target.value
                });
            }
        },
        getFilterValue(key) {
            if (this.filters.length) {
                for (let i = 0; i < this.filters.length; i++) {
                    if (this.filters[i]['name'] === key) {
                        return this.filters[i]['value'];
                    }
                }
            }
        },

        viewUrl(item) {
            if (this.viewLink) {
                if (this.viewLink.includes('{slug}')) {
                    return this.viewLink.replace('{slug}', item.slug);
                }
                if (this.viewLink.includes('{id}')) {
                    return this.viewLink.replace('{id}', item.id);
                }

                return this.viewLink;
            }

            return `${this.resourceUrl}/${item.id}`;
        },
        editUrl(item) {
            return this.editLink
                ? `${this.editLink}`
                : `${this.resourceUrl}/${item.id}/edit`;
        },
        duplicateUrl(item) {
            return this.duplicateLink
                ? `${this.duplicateLink}`
                : `${this.resourceUrl}/${item.id}/duplicate`;
        },
        deleteUrl(item) {
            return this.deleteLink
                ? `${this.deleteLink}`
                : `${this.resourceUrl}/${item.id}/delete`;
        },
        builderUrl(item) {
            return this.builderLink
                ? `${this.builderLink}/${item.uuid}`
                : `${this.resourceUrl}/${item.id}/builder`;
        },
        paginationChanged(page) {
            this.currentPage = page;
            this.getItems();
        },
        perPageChanged(perPage) {
            this.perPage = parseInt(perPage);
            this.getItems();
        },
        searchChanged(searchQuery) {
            this.searchQuery = searchQuery;
            this.getItems();
        },
        setAsSelectedItem(item, index) {
            this.selectedItem = item;
        },
        isSelected(item, index) {
            return this.selectedItem && this.selectedItem.id === item.id;
        },
        itemIndex(item, index) {
            return (index + (this.perPage * (this.currentPage - 1))) + 1;
        },
        resetSearchQuery() {
            window.EventBus.$emit('resetSearchQuery');
            this.searchQuery = null;
            this.state = 'loading';
            this.getItems();
        },
    },
    mounted() {
        this.getItems();
    },
    watch : {
        filters : 'getItems'
    }
}
</script>
