<template>
    <div class="filter" ref="filterEl">
        <slot name="filter"></slot>
    </div>
    <ElConfigProvider :size="isMobile ? '' : 'small'">
        <ElTable :data="tableData" :height="tableHeight" stripe v-loading="loading">
            <slot></slot>
        </ElTable>
    </ElConfigProvider>
    <div class="mt-4 flex justify-center">
        <ElPagination
            ref="paginEl"
            :layout="isMobile ? 'total, pager' : 'total, sizes, prev, pager, next, jumper'"
            v-model:page-size="pageConfig.pageSize"
            v-model:current-page="page"
            :total="total"
            :small="!isMobile"
        />
    </div>
</template>
<script setup>
import { ref, onMounted, computed, watch, inject } from 'vue'
import { http } from '@/plugins/http'
import { ElMessage } from 'element-plus'
import { useStorage, useElementBounding, useWindowSize } from '@vueuse/core'

const props = defineProps({
    url: {
        type: String,
        required: true
    },
    where: {
        type: Object,
        default: () => ({})
    },
    order: {
        type: Object,
        default: () => ({ createdAt: 'DESC' })
    }
})
const search = computed(() => {
    const where = { ...(props.where || {}) }
    Object.keys(where).forEach((key) => {
        if (where[key] === null) {
            delete where[key]
        }
    })
    return {
        where: props.where,
        order: props.order
    }
})

const filterEl = ref(null)
const paginEl = ref(null)
const { height: filterHeight } = useElementBounding(filterEl)
const { height: paginHeight } = useElementBounding(paginEl)
const { height: windowHeight } = useWindowSize()
const tableHeight = computed(() => windowHeight.value - 120 - filterHeight.value - paginHeight.value)
const isMobile = inject('isMobile')

const tableData = ref([])
const page = ref(1)
const pageConfig = useStorage('pageConfig', {
    pageSize: 20
})

const total = ref(0)
const loading = ref(false)
async function getData() {
    try {
        loading.value = true
        const res = await http.post(props.url, {
            page: {
                page: page.value,
                limit: pageConfig.value.pageSize
            },
            search: search.value
        })
        loading.value = false
        tableData.value = res.items
        total.value = res.meta.totalItems
    } catch (e) {
        loading.value = false
        ElMessage.error(e.message)
    }
}
onMounted(() => {
    getData()
})
watch(search, () => {
    console.log('search changed')
    if (page.value !== 1) {
        page.value = 1
    } else {
        getData()
    }
})
watch([page, pageConfig], () => {
    console.log('page changed')
    getData()
})
defineExpose({
    refresh() {
        getData()
    }
})
</script>
<style lang="less" scoped>
.filter {
    :deep(> *) {
        margin-bottom: 15px;
        margin-right: 15px;
    }
}
</style>
