<script setup lang="ts">
import { useElementBounding, useVirtualList } from '@vueuse/core';
import { computed, ref } from 'vue';

interface Props {
    list?: any[];
    itemHeight: number;
    headerHeight?: number;
    footerHeight?: number;
    bottom?: string; // FIXME: use css variable
}


const props = withDefaults(defineProps<Props>(), {
    list: () => [],
});


const { list: values, containerProps, wrapperProps } = useVirtualList(computed(() => props.list), {
    itemHeight: () => props.itemHeight,
    overscan: 3
})

const tableTop = ref<HTMLSpanElement | null>(null);
const { bottom: offset } = useElementBounding(tableTop);
const ypx = computed(() => {
    let y = (offset.value ?? 0) + 'px';

    if (props.bottom) {
        y = `calc(${y} + ${props.bottom})`;
    }
    return y;
})
const computedHeaderHeight = computed(() => {
    const h = props.headerHeight ?? props.itemHeight ?? 0;
    
    return h + 'px';
})
const computedFooterHeight = computed(() => {
    const h = props.footerHeight ?? 0;
    
    return h + 'px';
})
const computedWrapperProps = computed(() => ({
    ...wrapperProps.value,
    style: {
        ...wrapperProps.value.style,
        height: `calc(${wrapperProps.value.style.height} + ${computedHeaderHeight.value} + ${computedFooterHeight.value} + 1px)`
    }
}))
const itemHeightStyle = computed(() => {
    const h = props.itemHeight ?? 0;
    
    return h + 'px';
})
</script>

<template>
    <span ref="tableTop" class="h-0" />
    <div v-if="list.length > 0" v-bind="containerProps" class="table-container">
        <div v-bind="computedWrapperProps">
            <table>
                <slot :list="values" />
            </table>
        </div>
    </div>
    <slot v-else name="empty" />
</template>

<style scoped>
@reference "tailwindcss";
div.table-container {
    @apply bg-slate-600;
    max-height: calc(100vh - v-bind(ypx));
    :deep(>div) {
        @apply bg-slate-800;
        >table {
            >thead {
                @apply sticky z-10;
                top: -1px;
            }
            >tfoot {
                @apply bg-slate-600 sticky z-10;
                bottom: -1px;
            }
            >*>tr, >*>tr>td {
                height: v-bind(itemHeightStyle);
            }
        }
    }
    &::-webkit-scrollbar-track {
        margin-top: v-bind(computedHeaderHeight);
        margin-bottom: v-bind(computedFooterHeight);
    }
}
</style>