<template>

    <div class="m-0 h-100 w-100 p-2 rounded bg-gradient bg-dark-subtle">
    
        <div class="card shadow mb-2" style="background-color: #23395d;" :class="cardClass">
        
            <div class="card-header p-0"> 
        
                        <h3 class="pt-3">
                            {{ title }} 
                        </h3>
        
                    <div class="row pt-2 pb-1 mx-1">
                        
                        <div class="col-md-1 row mx-0 px-2">
                            <button v-if="allowNew" type="button" class="btn btn-block btn-dark" :disabled="loading" @click="popForm(0)">New</button>
                        </div>
                        <div class="col-md-3 p-0">
                            <select v-model="rowLimit" class="bg-primary-subtle form-select form-select-lg h-100"
                            :aria-label="title+' Table Data'" @change="this.changeLimit()">
                                <option value=5 selected>5</option>
                                <option value=10>10</option>
                                <option value=15>15</option>
                                <option value=20>20</option>
                            </select>
                        </div>
                        <float-inp type="text" label="Search" class="col-md-7 px-1" label-class="text-dark fw-bold" input-class="bg-primary-subtle bg-gradient input" v-model="searchQuery"></float-inp>                
                        <div class="col-md-1 row mx-0 px-1">
                            <button type="button" style="background-color: #1e7145;" class="btn pill-left w-50 h-100" @click="getTable()">
                                <svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 512 512">!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.<path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"/></svg>
                            </button>
                            <button type="button" style="background-color: #1e7145;" class="btn pill-right w-50 h-100" @click="refreshPage">
                                <svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 512 512">!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.<path d="M105.1 202.6c7.7-21.8 20.2-42.3 37.8-59.8c62.5-62.5 163.8-62.5 226.3 0L386.3 160H352c-17.7 0-32 14.3-32 32s14.3 32 32 32H463.5c0 0 0 0 0 0h.4c17.7 0 32-14.3 32-32V80c0-17.7-14.3-32-32-32s-32 14.3-32 32v35.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0C73.2 122 55.6 150.7 44.8 181.4c-5.9 16.7 2.9 34.9 19.5 40.8s34.9-2.9 40.8-19.5zM39 289.3c-5 1.5-9.8 4.2-13.7 8.2c-4 4-6.7 8.8-8.1 14c-.3 1.2-.6 2.5-.8 3.8c-.3 1.7-.4 3.4-.4 5.1V432c0 17.7 14.3 32 32 32s32-14.3 32-32V396.9l17.6 17.5 0 0c87.5 87.4 229.3 87.4 316.7 0c24.4-24.4 42.1-53.1 52.9-83.7c5.9-16.7-2.9-34.9-19.5-40.8s-34.9 2.9-40.8 19.5c-7.7 21.8-20.2 42.3-37.8 59.8c-62.5 62.5-163.8 62.5-226.3 0l-.1-.1L125.6 352H160c17.7 0 32-14.3 32-32s-14.3-32-32-32H48.4c-1.6 0-3.2 .1-4.8 .3s-3.1 .5-4.6 1z"/></svg>
                            </button>
                        </div>
                    
                    </div>
                    
                    <hr style="background-color: white; height: 2px;" class="mx-3">
                    
                    <nav aria-label="..." class="p-0 mx-1">
                    
                        <ul v-if="!loading" class="pagination px-0">
    
                            <li class="page-item hand" :class="table.curPage==1 ? 'page-item disabled' : ''">
                                <a class="page-link bg-warning border border-0" @click.prevent="prevPage" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            </li>
    
                            <li v-for="p, ind in table.pages" :key="ind" class="page-item" >
                                <a class="page-link text-bg-secondary border-0" 
                                    :class="p==table.curPage? 'bg-white text-dark fw-bold': ''"
                                    @click.prevent="setOffset(p)" >{{ p }}</a>
                            </li>                        
                            
                            <li class="page-item hand" :class="table.curPage==table.pages ? 'page-item disabled' : ''">
                                <a class="page-link bg-warning border-0" @click.prevent="nextPage" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            </li>
                        
                        </ul>
                    
                    </nav>
                
                </div>
                    
            </div> 
            
            <div class="card-body p-0" id="cdModal0">
            
                <table v-if="!loading" class="table table-sm table-bordered text-light rounded-pill table-responsive bg-gradient" :class=tableClass>
            
                    <thead class="bg-dark">
                
                        <tr>
                            <th class="table-dark border-0 border-dark rounded-1" v-for="h,ind in Object.keys(headers)" :key="ind" v-show="!hidden.includes(h)">
                                <div>
                                    <a class="hand" @click="sortTableAsc(h, $event)">
                                        <svg xmlns="http://www.w3.org/2000/svg" height="14" width="8.75" viewBox="0 0 320 512">
                                            <path :fill="(columnName==h && direction=='ASC')? '#FFD43B' : 'grey'" d="M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H288c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z"/>
                                        </svg>
                                    </a>
                                        {{ headers[h] }}                                 
                                    <a class="hand" @click="sortTableDesc(h)">
                                        <svg xmlns="http://www.w3.org/2000/svg" height="14" width="8.75" viewBox="0 0 320 512">
                                            <path :fill="(columnName==h && direction=='DESC')? '#FFD43B' : 'grey'" d="M137.4 374.6c12.5 12.5 32.8 12.5 45.3 0l128-128c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8L32 192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l128 128z"/>
                                        </svg>
                                    </a>
                                </div>
                            </th>
                        </tr>
                  
                    </thead>
                  
                    <tbody>
                        <tr v-for="r,ind in table.rows" :key="ind" @click.prevent="getItemData(r.id)">
                            <td class="border-0 border-dark rounded-1" v-for="h,indx in Object.keys(headers)" v-show="!hidden.includes(h)" :key="indx">
                                <slot v-if="h=='status'">
                                    {{ statusIcon(r[h]) }}
                                </slot>
                                <slot v-else-if="multiCols.cols.includes(h)">
                                    <span class="badge rounded-pill bg-primary mx-1" v-for="item,i in r[h]" :key="i">
                                        {{ item.name }} 
                                        <span class="badge rounded-pill bg-warning text-dark mx-1" v-if="Array.isArray(item)">
                                            ({{ item.length }})
                                        </span>
                                        <span class="badge rounded-pill bg-warning text-dark mx-1" v-else-if="multiCols.subTexts[h].length>0"> 
                                            
                                            <i v-for="s,is in multiCols.subTexts[h]" :key="is"> (
                                                <b v-if="multiCols.prefix.has(s)">{{ multiCols.prefix.get(s) }}</b>
                                                 {{ item[s] }} 
                                                <b v-if="multiCols.suffix.has(s)">{{ multiCols.suffix.get(s) }}</b>
                                            )
                                            </i>
                                        </span>
                                    </span> 
                                </slot>
                                <slot v-else>{{ r[h] }}</slot>

                            </td>
                        </tr>
                  </tbody>
                
                </table>
                
                <div v-else>
                    
                    <h1>{{ statusMessage }}</h1>
                    
                    <span v-show="!subMessage" class="spinner-border text-primary" role="status">
                      <span class="visually-hidden">Loading...</span>
                    </span>
                    
                    <h3>{{ subMessage }}</h3>
                
                </div>
            
            </div>
            
            <transition>
               <genFormModal v-if="showModal && genForm" @close="showModal=false" title="Hello there" :firstSelect="firstSelect"
                    :row-data="rowData" :headerTypes="headerTypes" :headers="headers" :add-cols="addCols" :hidden="hidden"
                      :fullScreen="false" @apply="submitForm($event)" @delData="delData($event)" :getItemList="getItemList">
                </genFormModal>            
            </transition>
    
    </div>
             
    </template>
    
    <style>
    
        .pill-left {
            border-radius: 7px 0px 0px 7px;
        }
    
        .pill-right {
            border-radius: 0px 7px 7px 0px;
        }
    
        td {
            text-align: left;
        }
    
    </style>
    
    <script>
    
    import genFormModal from '@/components/mods/genFormModal.vue';
    import floatInp from '@/parts/floatInp.vue';
    /* import axios from 'axios'; */
    export default {
        components:{
            genFormModal,
            floatInp
        },
        props:{
            allowNew:{
                type:Boolean,
                default:true
            },
            getItemList:{
                type:Array,
                default:new Array()
            },
            firstSelect:{
                default: new Object({table:'none',colName:'none'}),
                type:Object
            },
            genForm:{
                default:true,
                type:Boolean
            },
            title:{
                default: "Data Table",
                type:[Number,String,Object]
            },
            tableClass:{
                default:"table-bordered",
                type:String
            },
            cardClass:{
                default:"text-white",
                type:String
            },
            links:Object,
            tableName:String,
            addCols:{
                type:Object,
                default:new Object()
            },
            ddLinks:String,
            hidden:{
                type:Array,
                default:new Array()
            },
            headers:{
                type:Object,
                default:new Object()
            },
            multiCols:{
                type:Object,
                default:new Object ({cols:[],subTexts:[]})
            },
        },
        data(){
            return {
                rowLimit: 5,
                direction: 'DESC',
                columnName: 'id',
                loading: true,
                offset: 0,
                table:{ 
                        rows:{},
                        rowCount: 0,
                        pages: 0,
                        curPage:1
                },
                statusMessage:"loading....",
                subMessage:null,
                formData:{
                            name:null,
                            acronym:null,
                            type:null
                        },
                showModal:false,
                searchQuery:null,
                rowData:{},
                headerTypes:{},
                ddHolder:{}
    
            }
        },
        methods:{
            prevPage() {
    
                if (this.table.curPage > 1) {                
                    this.table.curPage = this.table.curPage-1;
                    this.offset = (this.table.curPage-1)*this.rowLimit;
                    this.getTable();
                }
    
            },
            nextPage() {
    
                if (this.table.curPage < this.table.pages) {
                    this.table.curPage = this.table.curPage+1;
                    this.offset = (this.table.curPage-1)*this.rowLimit;
                    this.getTable();
                }
                
            },
            changeLimit() {
                this.direction = 'DESC';
                this.columnName = 'id';
                this.table.curPage = 1;
                this.offset = 0;
                this.searchQuery = null;
                this.getTable();
            },
            refreshPage() {
                this.rowLimit = 5;
                this.direction = 'DESC';
                this.columnName = 'id';
                this.table.curPage = 1;
                this.offset = 0;
                this.searchQuery = null;
                this.getTable();
            },
            setOffset(p) {
                this.table.curPage=p;
                this.offset = (this.table.curPage-1)*this.rowLimit;
                this.getTable();
            },
            sortTableAsc(h) {
                this.columnName = h;
                this.direction = "ASC";
                this.getTable();
            },
            sortTableDesc(h) {
                this.columnName = h;
                this.direction = "DESC";
                this.getTable();
            },
            notObj(title,msg,type) {
                return {
                    title: title,
                    message: msg,
                    type:type
                }
            },
            popForm(id) {
                if(id<1 || id==null){
                    Object.keys(this.headers).forEach(key => {
                        this.rowData[key]=null;
                    });
                }
                if(this.genForm) this.showModal = true;
                else {
                    this.$emit('popForm',{
                            rowData:this.rowData,
                            headers:this.headers
                        });
                    
            }
            },
            async getTable() {
                this.loading = true;
                await this.$store.getters.getAxios.post(this.links.table,{/* table:this.tableName, */
                                                        col: this.columnName,
                                                        dir: this.direction,
                                                        limit: Number(this.rowLimit), 
                                                        offset: this.offset,
                                                        ent_id:this.$store.getters.getEntity,
                                                        search: this.searchQuery
                                                        })
                    .then(resp=>{
                        if(resp.data.isLoggedIn){
                            if(resp.data.data){                        
                                /* console.log(resp.data.data); */
                                var tData =  resp.data.data;
                                this.table.rows = tData["rows"];
                                this.table.rowCount = tData["rowCount"];
                                
                                this.table.pages = Math.ceil(this.table.rowCount/this.rowLimit);
                                this.loading=false;
                                this.subMessage=null;
                            }
                            else this.$store.commit('addAlert', {
                                                    title: "Error Getting Data",
                                                    message: "Try after some time",
                                                    type: 'danger'
                                                });
                        }
                        else this.$store.dispatch('loggedOut');
                    })
                    // eslint-disable-next-line
                    .catch(err=>{
                        this.statusMessage=`Error`;
                        this.subMessage=" No or Improper Data!";    
                    })
            },
            async submitForm(e) {
                this.loading=true;
                var action = e.id<1? 'insert' : 'edit';
                e['table']=this.tableName;
                
                
                await this.$store.getters.getAxios.post(this.links[action],e)
                    .then(resp=>{
                        if(resp.data.success){
                            var respData =  JSON.parse(resp.data.data);                        
                            this.$store.commit('pushNotif',this.notObj(respData.title,respData.msg,respData.type));
                            this.getTable();
                        }
                        else
                        this.$store.commit('pushNotif',this.notObj('Error Getting Data!',resp.data.message,'danger'));
                    })
                    // eslint-disable-next-line
                    .catch(err=>{
                        
    
                    })
            },
            async getItemData(id) {
                //this.loading=true;
                await this.$store.getters.getAxios.post(this.links.getItem,{id:id, table:this.tableName})
                    .then(resp=>{
                        if(resp.data.isLoggedIn){
                            if(resp.data.data){
                                this.rowData =  resp.data.data;
                                this.popForm(id);
                            }
                            else this.$store.commit('addAlert', {
                                                    title: "Error Getting Data",
                                                    message: "Try after some time",
                                                    type: 'danger'
                                                });
                        }
                        else this.$store.dispatch('loggedOut');
                        //this.loading=false;
                        this.subMessage=null;
                    })
                    // eslint-disable-next-line
                    .catch(err=>{
                        this.statusMessage=`Error`;
                        this.subMessage=err;
    
                    })
            },
            async delData(e) {
                await this.$store.getters.getAxios.post(this.links.delItem,{id:e.id, table:this.tableName})
                    .then(resp=>{
                        if(resp.data.success){
                            var rd =  JSON.parse(resp.data.data);
                            this.$store.commit('pushNotif',this.notObj(rd.title,rd.msg,rd.type));
                            this.getTable();
                        }
                        else 
                        this.$store.commit('pushNotif',this.notObj('Error Deleting Data!','Try after some time','danger'));
                        //this.loading=false;
                        this.subMessage=null;
                    })
                    // eslint-disable-next-line
                    .catch(err=>{
                        this.statusMessage=`Error`;
                        this.subMessage=err;
    
                    })
            },
            async getDropDownData(table,colName) {
                    this.loading=true;
                    await this.$store.getters.getAxios.post(this.ddLinks,{table:table,colName:colName})
                        .then(resp=>{
                            this.ddHolder[table] =  JSON.parse(resp.data.data);
                            this.ddList.forEach(e=>{
                                if(e.depsOn==null)this.getDropDownData(e.table,e.colName);
                            });
                        })
                        // eslint-disable-next-line
                        .catch(err=>{
                            this.$store.commit('addAlert', {
                                title: "Error Getting Data",
                                message: "Try after some time",
                                type: 'danger'
                            });
        
                        })
            },
                statusIcon(data) {
                return (data == 1 || data === 'active') ? '✅' : '❌';
            }
            },
        
        async mounted() {
            await this.getTable();
        }
        
    }
    </script>
    <style>
    th {
        text-align: justify;
        min-width: 100px;
    }
    a{
        cursor: pointer;
    }
    </style>