import { createOptionBuilder, isPromise, applyPluginBaseOptions } from '@vue-layout/core';
import { unref, h, mergeProps, isRef, defineComponent, computed } from 'vue';

function buildPaginationOptions(options) {
    const { buildOrFail, build } = createOptionBuilder('pagination');
    return {
        ...options,
        busy: options.busy ?? false,
        tag: buildOrFail({
            key: 'tag',
            value: options.tag,
            alt: 'ul'
        }),
        class: buildOrFail({
            key: 'class',
            value: options.class,
            alt: 'pagination'
        }),
        itemTag: buildOrFail({
            key: 'itemTag',
            value: options.itemTag,
            alt: 'li'
        }),
        itemClass: buildOrFail({
            key: 'itemClass',
            value: options.itemClass,
            alt: 'page-item'
        }),
        linkClass: buildOrFail({
            key: 'linkClass',
            value: options.linkClass,
            alt: 'page-link'
        }),
        linkActiveClass: buildOrFail({
            key: 'linkActiveClass',
            value: options.linkActiveClass,
            alt: 'active'
        }),
        prevTag: buildOrFail({
            key: 'prevTag',
            value: options.prevTag,
            alt: 'i'
        }),
        prevClass: build({
            key: 'prevClass',
            value: options.prevClass,
            alt: []
        }),
        prevContent: build({
            key: 'prevContent',
            value: options.prevContent
        }),
        nextTag: buildOrFail({
            key: 'nextTag',
            value: options.nextTag,
            alt: 'i'
        }),
        nextClass: build({
            key: 'nextClass',
            value: options.nextClass,
            alt: []
        }),
        nextContent: build({
            key: 'nextContent',
            value: options.nextContent
        })
    };
}
function buildPagination(input) {
    const options = buildPaginationOptions(input);
    let totalPages = 1;
    let currentPage = 1;
    if (options.total > 0 && options.limit > 0) {
        totalPages = Math.max(Math.ceil(options.total / options.limit), 1);
        currentPage = Math.floor(options.offset / options.limit) + 1;
    }
    const betweenPages = [];
    for(let i = currentPage - 2; i < currentPage + 2; i++){
        if (i > 0 && i <= totalPages) {
            betweenPages.push(i);
        }
    }
    const busy = unref(options.busy);
    const load = (page)=>{
        if (busy || page === currentPage) {
            return undefined;
        }
        if (isRef(options.busy)) {
            options.busy.value = true;
        }
        const data = {
            page,
            offset: (page - 1) * options.limit,
            limit: options.limit,
            total: totalPages
        };
        const output = options.load(data);
        if (isPromise(output)) {
            return output.finally(()=>{
                if (isRef(options.busy)) {
                    options.busy.value = false;
                }
            });
        }
        if (isRef(options.busy)) {
            options.busy.value = false;
        }
        return output;
    };
    const renderPrevPage = ()=>{
        let content;
        if (options.prevClass || options.prevContent) {
            content = h(options.prevTag, {
                class: options.prevClass
            }, options.prevContent);
        } else {
            content = [
                currentPage - 1
            ];
        }
        let prevPage = [];
        if (currentPage > 1) {
            prevPage = [
                h(options.itemTag, {
                    class: options.itemClass
                }, [
                    h('button', {
                        class: options.linkClass,
                        disabled: options.busy,
                        onClick ($event) {
                            $event.preventDefault();
                            return load(currentPage - 1);
                        }
                    }, [
                        content
                    ])
                ])
            ];
        }
        return prevPage;
    };
    const renderBetweenPages = ()=>{
        const children = [];
        for(let i = 0; i < betweenPages.length; i++){
            const node = h(options.itemTag, {
                class: options.itemClass
            }, [
                h('button', {
                    ...mergeProps({
                        ...betweenPages[i] === currentPage ? {
                            class: options.linkActiveClass
                        } : {}
                    }, {
                        class: options.linkClass
                    }),
                    disabled: options.busy,
                    onClick ($event) {
                        $event.preventDefault();
                        // eslint-disable-next-line prefer-rest-params
                        return load(betweenPages[i]);
                    }
                }, [
                    betweenPages[i]
                ])
            ]);
            children.push(node);
        }
        return children;
    };
    const renderNextPage = ()=>{
        let nextPage = [];
        let content;
        if (options.nextClass || options.nextContent) {
            content = h(options.nextTag, {
                class: options.nextClass
            }, options.nextContent);
        } else {
            content = [
                currentPage + 1
            ];
        }
        if (currentPage < totalPages) {
            nextPage = [
                h(options.itemTag, {
                    class: options.itemClass
                }, [
                    h('button', {
                        class: options.linkClass,
                        disabled: options.busy,
                        onClick ($event) {
                            $event.preventDefault();
                            return load(currentPage + 1);
                        }
                    }, [
                        content
                    ])
                ])
            ];
        }
        return nextPage;
    };
    return h(options.tag, {
        class: options.class
    }, [
        renderPrevPage(),
        renderBetweenPages(),
        renderNextPage()
    ]);
}

const Pagination = defineComponent({
    name: 'Pagination',
    props: {
        total: {
            type: Number,
            default: 0
        },
        limit: {
            type: Number,
            default: 0
        },
        offset: {
            type: Number,
            default: 0
        },
        busy: {
            type: Boolean,
            default: false
        },
        meta: {
            type: Object,
            default: undefined
        }
    },
    emits: [
        'load'
    ],
    setup (props, { emit }) {
        const meta = computed(()=>{
            if (typeof props.meta === 'undefined') {
                return {};
            }
            return props.meta;
        });
        return ()=>buildPagination({
                total: meta.value.total ?? props.total,
                limit: meta.value.limit ?? props.limit,
                offset: meta.value.offset ?? props.offset,
                busy: meta.value.busy ?? props.busy,
                load: (data)=>emit('load', data)
            });
    }
});

function install(instance, options) {
    options ?? (options = {});
    applyPluginBaseOptions(options);
    instance.component('Pagination', Pagination);
}
var index = {
    install
};

export { Pagination, buildPagination, buildPaginationOptions, index as default, install };
//# sourceMappingURL=index.mjs.map
