var VueGrid = (function () {
    return {
        name: 'grid',
        options: {
            compilerOptions: {
                isCustomElement: tag => tag === this.name
            }
        },
        props: ['id', 'columns', 'ondataload', 'limits', 'languages', 'url', 'height', 'pagination','search'],
        data() {
            return {
                axiosCancelToken: null,
                axiosSource: null,
                cssname: "gridjs-css",
                jsname: "gridjs-js",
                limit: [
                    { value: "10", text: "10" },
                    { value: "50", text: "50" },
                    { value: "100", text: "100" },
                    { value: "500", text: "500" },
                    { value: "1000", text: "1000" },
                    { value: "all", text: "Semua" },
                ],
                data: [],
                conf: {
                    pagination: this.pagination || {
                        enabled: true,
                        limit: 50,
                        resetPageonUpdate: false,
                        summary: true
                    },
                    fixedHeader: true,
                    height: this.height || 'auto',
                    columns: this.columns,
                    search: this.search||true,
                    language: this.languages || {
                        'search': {
                            'placeholder': '🔍 Cari...'
                        },
                    },
                    sort: true,
                    server: {
                        url: this.url,
                        data: (opts) => {
                            axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
                            if (this.axiosSource) {
                                this.axiosSource.cancel();
                            }
                            return new Promise((resolve, reject) => {
                                this.axiosCancelToken = axios.CancelToken;
                                this.axiosSource = this.axiosCancelToken.source();
                                axios({
                                    method: 'get',
                                    url: opts.url,
                                    cancelToken: this.axiosSource.token
                                }).then((response) => {
                                    if (response.request.responseURL.includes('login')) {
                                        Swal.fire({
                                            text: "Session Expired",
                                            confirmButtonText: 'Reload',
                                        }).then((result) => {
                                            if (result.isConfirmed) {
                                                window.location.href = '';
                                            }
                                        })
                                        return;
                                    }
                                    let d = this.ondataload(response.data);
                                    this.data = d;
                                    resolve({
                                        data: d
                                    })
                                }, (error) => {
                                    reject(error)
                                });
                            });
                        }
                    }
                }
            }
        },
        mounted() {
            this.appendJs();
            this.appendCss();
            this.initGrid();
        },
        methods: {
            initGrid() {
                if (typeof gridjs == 'undefined' && typeof this.grid == 'undefined') {
                    setTimeout(() => {
                        this.initGrid();
                    }, 50);
                } else {
                    if (this.limits && !this.ready) {
                        this.conf.plugins = [this.addLimit()];
                    }
                    this.grid = new gridjs.Grid(this.conf).render(document.getElementById(this.id));
                    document.addEventListener('change', (e) => {
                        switch (e.target.id) {
                            case "limit-" + this.id:
                                if (e.target.value == 'all') {
                                    this.grid.config.pagination.limit = this.data.length
                                } else {
                                    this.grid.config.pagination.limit = e.target.value
                                }
                                this.reload(true);
                                break;

                            default:
                                break;
                        }
                    });
                }
            },
            addLimit() {
                let id = "limit-" + this.id;
                let plg = {
                    id: id,
                    component: () => {
                        let lim = (typeof this.limits == "array" ? this.limits : this.limit);
                        let options = lim.map(e => `<option ${this.s(e.value)} value="${e.value}">${e.text}</option>`);
                        let e = `
                    <div class="select-position m-1">
                        <select class="gridjs-limits" id="${id}">
                            ${options.join(" ")};
                        </select>
                    </div>
                        `
                        return gridjs.html(e);
                    },
                    position: gridjs.PluginPosition.Header,
                }
                return plg;
            },
            s(v) {
                let limit = this.conf.pagination.limit || 10;
                return (v == limit || (v == 'all' && limit == this.data.length) ? "selected" : "")
            },
            reload(n = false) {
                if (this.grid) {
                    if (n) {
                        if (this.limits) this.conf.plugins = [this.addLimit()];
                        this.grid.updateConfig(this.conf);
                    }
                    this.grid.forceRender();
                }
            },
            appendJs() {
                if (!document.getElementById(this.jsname)) {
                    let head = document.getElementsByTagName('body')[0];
                    let script = document.createElement('script');
                    script.id = this.jsname;
                    script.src = '/vendors/gridjs/gridjs.production.min.js';
                    head.appendChild(script);
                }
            },
            appendCss() {
                if (!document.getElementById(this.cssname)) {
                    var head = document.getElementsByTagName('head')[0];
                    var link = document.createElement('link');
                    link.id = this.cssname;
                    link.rel = 'stylesheet';
                    link.type = 'text/css';
                    link.href = '/vendors/gridjs/theme/mermaid.min.css';
                    link.media = 'all';
                    head.appendChild(link);
                }
            },
        },
        watch: {
            url(v) {
                this.conf.server.url = v;
                this.reload(true)
            }
        },
        template: `
        <div :id="id"></div>
    `,
    }
})();
