<script setup lang="ts" generic="T extends {id: string}">
type VPage = {
    page: number;
    text: string | number;
    enabled: boolean;
} | {
    page?: never;
    text: string;
    enabled: false;
};

const props = withDefaults(defineProps<{
    data: T[];
    perPage?: number;
    marked?: (element: T) => boolean;
    fixed?: boolean;
    count?: boolean;
}>(), {
    perPage: 30,
});
const page = ref(0);

const dataPage = computed((): T[] => {
    return props.data.slice(page.value * props.perPage, (page.value + 1) * props.perPage);
});
const pages = computed((): number => {
    return Math.ceil(props.data.length / props.perPage);
});
const pagesRange = computed((): VPage[] => {
    const vPages = [];
    vPages.push({ page: 0, text: '«', enabled: page.value > 0 });
    vPages.push({ page: page.value - 1, text: '‹', enabled: page.value > 0 });
    for (let i = 0; i < pages.value; i++) {
        if (i <= 4 || (page.value - 3 <= i && i <= page.value + 3) || i >= pages.value - 3) {
            vPages.push({ page: i, text: i + 1, enabled: true });
        } else if (vPages[vPages.length - 1].text !== '…') {
            vPages.push({ text: '…', enabled: false } as const);
        }
    }
    vPages.push({ page: page.value + 1, text: '›', enabled: page.value < pages.value - 1 });
    vPages.push({ page: pages.value - 1, text: '»', enabled: page.value < pages.value - 1 });
    return vPages;
});

const navigateToPage = (to: number) => {
    page.value = to;
    focus();
};

const section = useTemplateRef<HTMLElement>('section');
const focus = () => {
    section.value?.scrollIntoView();
};

defineExpose({
    reset() {
        navigateToPage(0);
    },
    focus,
});
</script>

<template>
    <section ref="section" class="table-responsive scroll-mt-7">
        <div class="container" role="table">
            <nav v-if="pages > 1" class="d-flex justify-content-center p-2">
                <ul class="pagination pagination-sm justify-content-center mb-0">
                    <li
                        v-for="p in pagesRange"
                        :key="p.text"
                        :class="['page-item', p.page === page ? 'active' : '', p.enabled ? '' : 'disabled']"
                    >
                        <button v-if="p.enabled" type="button" class="page-link" @click="navigateToPage(p.page)">
                            {{ p.text }}
                        </button>
                        <span v-else class="page-link">
                            {{ p.text }}
                        </span>
                    </li>
                </ul>
            </nav>
            <div v-if="count" class="d-flex">
                <div class="col">
                    <T>table.count</T><T>quotation.colon</T>
                    <strong>{{ data.length }}</strong>
                </div>
            </div>
            <div class="row-header p-2 d-grid gap-2 border-top" role="row">
                <slot name="header"></slot>
            </div>
            <template v-if="data.length">
                <div
                    v-for="el in dataPage"
                    :key="el.id"
                    :class="['row-content p-2 d-grid gap-2 border-top', marked?.(el) ? 'marked' : '']"
                    role="row"
                >
                    <slot name="row" :el="el"></slot>
                </div>
            </template>
            <template v-else>
                <div class="d-flex">
                    <div class="text-center col">
                        <slot name="empty">
                            <Icon v="search" />
                            <T>table.empty</T>
                        </slot>
                    </div>
                </div>
            </template>
            <nav v-if="pages > 1" class="d-flex justify-content-center p-2 border-top">
                <ul class="pagination pagination-sm justify-content-center">
                    <li
                        v-for="p in pagesRange"
                        :key="p.text"
                        :class="['page-item', p.page === page ? 'active' : '', p.enabled ? '' : 'disabled']"
                    >
                        <button v-if="p.enabled" type="button" class="page-link" @click="navigateToPage(p.page)">
                            {{ p.text }}
                        </button>
                        <span v-else class="page-link">
                            {{ p.text }}
                        </span>
                    </li>
                </ul>
            </nav>
        </div>
    </section>
</template>

<style lang="scss">
    @import "~/assets/variables";

    .marked {
        border-inline-start: 3px solid $primary;
    }

    .row-content {
        background-color: var(--bs-table-bg);
        border-bottom-width: var(--bs-border-width);

        &:nth-child(odd) {
            background: rgba(var(--bs-emphasis-color-rgb), 0.05);
        }

        &:hover {
            background: rgba(var(--bs-emphasis-color-rgb), 0.075);
        }
    }
</style>
