<template>
    <div class="Datatable">
        <!-- Search-Box -->
        <div class="quad-grids-sm mob-items-xs">
            <div class="mar-10-b">
                <div class="input icon" v-if="isSearch">
                    <input type="text" v-model="searchVal" @keyup="searchEvent($event)" placeholder="Herhangi bir alan için arama yapabilirisiniz.">
                    <label class="fa fa-search"></label>
                </div>
            </div>
        </div>

        <!-- Table-Box -->
        <div class="dt-container">
            <!-- Loading -->
            <div class="loading-container align-center direction-y" v-if="loading" style="min-height: 445px">
                <h3 class="mar-30-b">Yükleniyor...</h3>
                <i class="text-size-24 fa fa-spin fa-spinner"></i>
            </div>
            <!-- Table -->
            <div class="dt-content" v-else>
                <!-- Table Head -->
                <div class="dt-row dt-row-head">
                    <span class="dt-cell dt-cell-head" v-for="(column, index) in Column" @click="sortTable(column.key, index)" v-if="column.visible">
                        <span>
                            {{column.value | capitalize}}
                            <i class="fa" :class="column.order"></i>
                        </span>
                    </span>
                    <span class="dt-cell dt-cell-head dt-cell-manage-buttons">Yönetim</span>
                </div>
                <!-- Table Body -->
                <ul>
                    <li v-for="(data, index) in Data" class="dt-row dt-row-body">
                        <div class="dt-cell-group dt-cell-group-visible">
                            <!-- Table Cells -->
                            <span v-for="column in Column" class="dt-cell dt-cell-body" v-if="column.visible">
                                <span v-if="typeof column.image == 'undefined'">{{getDeepData(index)[column.key]}}</span>
                                <img :src="getDeepData(index)[column.key]" class="dt-img" v-else>
                            </span>
                            <!-- Management Buttons Cell -->
                            <span class="dt-cell dt-cell-body dt-cell-manage-buttons">
                                <a :href="_replaceText(xhrUrl.edit, 'params', getDeepData(index)[primaryKey])" v-if="xhrUrl.edit" class="dt-btn dt-btn-edit">
                                    <i class="fa fa-pencil"></i><span>Düzenle</span>
                                </a>
                                <button @click="removeItem(getDeepData(index)[primaryKey], index)" v-if="xhrUrl.destroy" class="dt-btn dt-btn-destroy">
                                    <i class="fa fa-trash"></i><span>Sil</span>
                                </button>
                                <!-- Modal Button -->
                                <button :class="modalButtonProps.buttonClass" v-if="modalButtonProps" @click="clickedModal(data[primaryKey], index)" class="dt-btn dt-btn-no-text">
                                    <i :class="[index === clickedModalBtnIndex ? 'fa fa-spinner fa-spin' : modalButtonProps.iconClass]"></i>
                                </button>
                                <!-- Link Button -->
                                <a v-if="linkButton"
                                    :href="_replaceText(linkButton.href, '{id}', data[primaryKey])"
                                    v-html="linkButton.html"
                                    :class="linkButton.class"
                                    :style="linkButton.style"
                                    class="dt-btn"
                                ></a>
                                <!-- Drop Button -->
                                <div class="dropdown center dt-btn"
                                     v-if="dropButton"
                                     :id="'dt-dropdown-' + index"
                                >
                                    <a href="#"
                                       v-html="dropButton.link.html"
                                       :class="dropButton.link.class"
                                       :style="dropButton.link.style"
                                    ></a>
                                    <div class="drop-box">
                                        <ul>
                                            <li v-for="item in dropButton.item">
                                                <a :href="_replaceText(item.href, '{id}', data[primaryKey])"
                                                   :class="item.class"
                                                   :style="item.style"
                                                   v-html="item.html"
                                                ></a>
                                            </li>
                                        </ul>
                                    </div>
                                </div>
                                <!-- HIDDEN CELL TOGGLE BUTTON -->
                                <button class="dt-btn dt-btn-no-text dt-btn-circle" v-if="IS_SHOW_HIDDEN_CELL_BUTTON" @click="setVisible(index)">
                                    <i class="fa fa-plus" :class="{'open': data.visible === true }"></i>
                                </button>
                            </span>
                        </div>

                        <div class="dt-cell-hidden-group" :class="{'active' : data.visible}">
                            <div v-for="column in Column" class="dt-cell dt-cell-body" v-if="!column.visible">
                                <b class="fw-500 pad-5-r">{{column.value | capitalize}} :</b>
                                <span v-if="typeof column.image == 'undefined'">{{getDeepData(index)[column.key]}}</span>
                                <img :src="getDeepData(index)[column.key]" class="dt-img" v-else>
                            </div>
                        </div>

                    </li>
                </ul>
                <!-- Paginate -->
                <div class="align-center pad-10-y" v-if="isPagination === true">
                    <i class="fa fa-chevron-left" @click="changePage(query.page - 1)" v-if="query.page > 1"></i>
                    <span class="pad-10" v-for="n in compPageCount" @click="changePage(n)" :class="n == query.page ? 'active' : ''">{{n}}</span>
                    <i class="fa fa-chevron-right" @click="changePage(query.page + 1)" v-if="query.page < paginateOptions.last_page"></i>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import lodash from 'lodash'
    export default {
        props: {
            cell: {
                required: true,
                type: Array
            },
            xhrUrl: {
                required: true,
                type: Object
            },
            primaryKey: {
                type: String,
                default: "id"
            },
            isPagination: {
                type: Boolean,
                default: true
            },
            isOrderby: {
                type: Boolean,
                default: true
            },
            isSearch: {
                type: Boolean,
                default: true
            },
            refresh: {
                type: Boolean,
                default: false
            },
            modalButtonProps: Object,
            linkButton: Object,
            dropButton: Object
        },
        data() {
            return {
                Data: "",
                Column : "",
                orderClass: {},
                searchVal: '',
                pageShowItem: 10,
                query: {
                    "page": 1
                },
                paginateOptions: '',
                loading: false,
                _: lodash,
                clickedModalBtnIndex: -1, // This Variable Using For Modal Button Loading Animation,
                dropbuttonPass: true
            }
        },
        watch: {
            refresh(newVal) {
                if (newVal == true) {
                    this.sendXhrRequest();
                }
            }
        },
        computed: {
            IS_SHOW_HIDDEN_CELL_BUTTON() {
                let hasHiddenState = false;
                this.Column.forEach(item => {
                    if (item.visible === false) {
                        hasHiddenState = true;
                    }
                })
                return hasHiddenState;
            },
            compPageCount () {
                let pageStore = [];
                if (this.paginateOptions.last_page !== "undefined") {
                    let start  = this.query.page - 2 > 0 ? this.query.page - 2 : 1;
                    let finish = this.query.page + 2 < this.paginateOptions['last_page'] ? this.query.page + 2 : this.paginateOptions['last_page'];
                    for (let i = start; i <= finish; i++) {
                        pageStore.push(i)
                    }
                    return pageStore;
                }
            }
        },
        filters: {
            capitalize(value) {
                return value.charAt(0).toLocaleUpperCase('tr-TR') + value.slice(1)
            }
        },
        methods: {
            _replaceText(text, searchKey, replaceKey) {
                return text.replace(searchKey, replaceKey);
            },
            _arrayPluck(neddle, haystack) {
                let arr = [];
                haystack.forEach(collection => {
                    for (let key in collection) {
                        if (neddle == key)
                            arr.push(collection[key])
                    }
                })
                return arr;
            },

            getDeepData(index) {
                return this.$deepModel(this.Data[index])
            },

            addVisibleKey() {
                this.Data.forEach((input, index) => {
                    this.$set(this.Data[index], 'visible', false);
                })
            },
            addVisibleKeyForCell() {
                this.Column.forEach((cell, index) => {
                    this.$set(this.Column[index], 'visible', this.checkCellVisibility(cell));
                });
            },
            checkCellVisibility(cell) {
                if (cell.state === 'hidden') {
                    return false;
                } else if (cell.state === 'mobile' && window.innerWidth <= 768) {
                    return false;
                }
                return true;
            },
            setVisible(index) {
                this.Data[index].visible =! this.Data[index].visible;
                let h = 0;
                $('.dt-cell-hidden-group').eq(index).find('div').each(function () {
                    h += $(this).innerHeight();
                });

                if (!$('.dt-cell-hidden-group').eq(index).hasClass('active')) {
                    $('.dt-cell-hidden-group').eq(index).css('max-height', h + 'px');
                } else {
                    $('.dt-cell-hidden-group').eq(index).css('max-height', '0px');
                }
            },
            addOrderKeyInCell() {
                this.Column.forEach((cell) => {
                    this.$set(cell, "order", {"fa-sort": true})
                });
            },


            // Modal Click Function - Silinebilir
            clickedModal(id, index) {
                this.clickedModalBtnIndex = index;
                axios.get(this.modalButtonProps.xhrUrl.replace('params', id)).then(response => {
                   this.$store.commit('setModalData', response.data);
                   this.$store.commit('isModalShow', true);
                   this.$store.commit('setModalId', this.modalButtonProps.id);
                    this.clickedModalBtnIndex = -1;
                    this.$emit('dispatchUser', {id: id, index: index});
                }).catch(error => {
                    console.log(error.response);
                    this.clickedModalBtnIndex = -1;
                });
            },

            sendXhrRequest() {
                axios.get(this.xhrUrl.index, {
                    params: this.query
                }).then(response => {
                    if (this.isPagination) {
                        this.setPaginateOptions(response.data);
                        this.Data = response.data.data;
                    } else {
                        this.Data = response.data;
                    }
                    this.addVisibleKey();
                    this.loading = false;
                    this.$emit('refresh', true)
                }).catch(error => {
                    console.log(error.response);
                    this.loading = false;
                })
            },
            setPaginateOptions (response) {
                // Laravel'den gelen sayfalama options'ları alınıyor (eg: last_page)
                this.paginateOptions = new Object();
                for (let key in response) {
                    if (key != "data") {
                        this.paginateOptions[key] = response[key];
                    }
                }
            },
            changePage(page) {
                if (page > 0) {
                    this.loading = true;
                    this.query['page'] = page;
                    this.sendXhrRequest();
                }
            },
            searchEvent(e) {
                if (e.keyCode == 27 || e.target.value.length == 0) {
                    this.loading                 = true;
                    this.query['search']         = undefined;
                    this.query['search-columns'] = undefined;
                    this.sendXhrRequest();
                    this.query.page = 1;
                    this.searchVal = '';
                } else {
                    this.searchWithDebounce(e);
                }
            },
            searchWithDebounce: _.debounce(function (e) {
                this.loading                 = true;
                this.query['search']         = e.target.value;
                this.query['search-columns'] = JSON.stringify(this._arrayPluck("key", this.Column));
                this.sendXhrRequest();
                this.query.page = 1;
            }, 500),
            sortTable(column, arrKey) {
                if (this.isOrderby) {
                    this.loading = true;
                    this.addOrderKeyInCell(); // reset order class
                    if (column === this.query['order-column']) {
                        if (typeof this.query['order'] === "undefined") {
                            this.query['order']          = 'asc';
                            this.Column[arrKey]['order'] = {'fa-sort-asc': true}
                        } else if (this.query['order'] === 'asc') {
                            this.query['order']          = 'desc';
                            this.Column[arrKey]['order'] = {'fa-sort-desc': true}
                        } else {
                            this.query['order']          = undefined;
                            this.Column[arrKey]['order'] = {'fa-sort': true}
                        }
                    } else {
                        this.query['order']          = 'asc';
                        this.Column[arrKey]['order'] = {'fa-sort-asc': true}
                    }
                    this.query['order-column'] = column;
                    this.sendXhrRequest();
                }
            },
            removeItem(dbId, orderId) {
                const replacedUrl = this._replaceText(this.xhrUrl.destroy, "params", dbId);
                axios.delete(replacedUrl).then(response => {
                    console.log(response.data);
                    this.sendXhrRequest();
                    $('#app').snackbar({status: 'success', message: response.data});

                }).catch(error => {
                    console.log(error.response.data);
                    $('#app').snackbar({status: 'danger', message: error.response.data})
                });
            },
        },
        updated() {
            if (Array.isArray(this.Data) && this.dropbuttonPass) {
                this.dropbuttonPass = false;
                this.Data.forEach((data, index) => {
                    $('#dt-dropdown-' + index).dropdown();
                })
            }
        },
        mounted() {
            this.Column = this.cell;
            this.addOrderKeyInCell();
            this.addVisibleKeyForCell();
            window.onresize = () => {
                this.addVisibleKeyForCell();
            }
            this.loading = true;
            this.sendXhrRequest();
        },
        sockets: {
            test(data) {
                console.log(data);
                this.Data.unshift(JSON.parse(data));
            }
        }
    }
</script>

<!--
*** SERVER SIDE VUE DATATABLE ***
    /-- Requirements --/
        * Vue
        * Vue-Deepset
        * Axios
        * Lodash
        * Styland
    /-- API --/
        * cell
            - type: Array in Object
                - Object Keys
                    - text:  String - Required
                    - value: String - Required
                    - state: String - Optional - ('mobile' | 'hidden')
            - required
-->