<template>
    <DataTable
        class="p-datatable-sm"
        :value="records"
        :lazy="true"
        :auto-layout="true"
        :paginator="true"
        :rows="10"
        v-model:filters="filters"
        ref="dt"
        :loading="loading"
        :total-records="totalRecords"
        :globalFilterFields="searchableColumns"
        @page="onPage"
        @sort="onSort"
        @filter="onFilter"
        filter-display="row"
        responsive-layout="stack"
        breakpoint="960px"
        :state-key="stateKey"
        state-storage="session"
        currentPageReportTemplate="Showing {first} to {last} of {totalRecords} records"
        paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[5,10,15,25,50]"
    >
        <template #loading>
            Loading...
        </template>
        <template #header>
            <div class="flex flex-wrap gap-2 justify-between items-center">
                <div>
                    <div class="flex items-center gap-2">
                        <Button @click="loadLazyData" class="p-button-text p-button-plain" icon="pi pi-refresh"/>
                        <slot name="header">
                            <h5 class="font-semibold">{{title}}</h5>
                        </slot>
                    </div>
                </div>
                <div class="p-input-icon-left max-w-[360px]">
                    <i v-if="!filters['global'].value" class="pi pi-search" />
                    <i v-else v-if="filters['global'].value" class="pi pi-times" @click="filters['global'].value = null; onFilter()"></i>
                    <InputText v-model="filters['global'].value" @input="debounce(onFilter,500)" placeholder="Keyword Search" />
                </div>
            </div>
        </template>
        <template #empty>
            <p class="text-center">No records found.</p>
        </template>
        <slot></slot>
    </DataTable>
</template>

<script lang="ts">
import {defineComponent, onMounted, Ref, ref, toRef, watch} from "vue";
import {FilterMatchMode} from "primevue/api";
import {useDebounce} from "@/composables/debounce";
import axios from "axios";
import InputText from "primevue/inputtext";
import DataTable from "primevue/datatable";
import Button from "primevue/button";

export default defineComponent({
    name: "PrimeDatatables",
    components: {
        DataTable,
        InputText,
        Button,
    },
    props: {
        apiUrl: String,
        title: String,
        refresh: String,
        defaultSortField: String,
        defaultSortDesc: {
            type: Boolean,
            default: true,
        },
        searchableColumns: {
            type: Array,
            default: [],
        },
        columnFilters: {
            required: true,
            type: Object,
            default: {}
        },
        stateKey: String,
    },
    setup(props) {
        onMounted(async () => {
            // loading.value = true;
            // console.log(filters.value);
            lazyParams.value = JSON.parse(sessionStorage.getItem(stateKey.value as string) as string);
            if (!lazyParams.value) {
                lazyParams.value = {
                    first: 0,
                    filters: filters.value,
                    rows: 10,
                }
            }
            lazyParams.value.page = Math.fround(parseInt(lazyParams.value.first)/parseInt(lazyParams.value.rows || 10))
            console.log(lazyParams.value);
            await loadLazyData();
        })

        const refresh = toRef(props, "refresh");
        watch(refresh,(val) => {
            loadLazyData();
        });

        const dt = ref();
        const debounce = useDebounce();
        const loading = ref(false);
        const totalRecords = ref(0);
        const records = ref();
        const filtersProp = toRef(props,"columnFilters");
        const filters = ref({});
        filters.value = {
            ...filtersProp.value,
            global: {value: '', matchMode: FilterMatchMode.CONTAINS}
        }
        const searchableColumns = toRef(props, "searchableColumns") as Ref<Array<string>>
        const lazyParams: Ref<any> = ref({});
        const apiUrl = toRef(props, "apiUrl") as Ref<string>;
        const stateKey = toRef(props,'stateKey');
        const loadLazyData = async () => {
            loading.value = true;
            lazyParams.value.filters = filters.value;
            if (!lazyParams.value.sortField) {
                lazyParams.value.sortField = toRef(props, "defaultSortField").value;
            }
            if (![-1,1].includes(lazyParams.value.sortOrder)) {
                lazyParams.value.sortOrder = toRef(props, "defaultSortDesc").value ? -1 : 1;
            }
            try {
                const res = await axios.get(apiUrl.value,{
                    params: {
                        dt_params: JSON.stringify(lazyParams.value),
                        searchable_columns: JSON.stringify(searchableColumns.value),
                    },
                });

                records.value = res.data.data ?? [];
                totalRecords.value = res.data.total;
                loading.value = false;
            } catch (e) {
                records.value = [];
                totalRecords.value = 0;
                loading.value = false;
            }
        };

        const onPage = (event) => {
            lazyParams.value = event;
            // lazyParams.value.filters = filters.value;
            loadLazyData();
        };
        const onSort = (event) => {
            lazyParams.value = event;
            loadLazyData();
        };
        const onFilter = () => {
            // lazyParams.value.filters = filters.value;
            //Reset pagination first
            // lazyParams.value.originalEvent = {first: 0, page: 0}
            // onPage(lazyParams.value);
            loadLazyData();
        }

        return {
            dt,
            loading,
            totalRecords,
            records,
            filters,
            lazyParams,
            loadLazyData,
            onPage,
            onSort,
            onFilter,
            debounce
        }
    }
});
</script>

<style scoped>

</style>