import { createComponentOptionsManager, isPromise, installStoreManager, applyStoreManagerOptions } from '@vuecs/core';
import { unref, h, mergeProps, isRef, defineComponent } from 'vue';

function calculatePage(context) {
    return Math.floor(context.offset / context.limit) + 1;
}
function calculatePagesTotal(context) {
    return Math.max(Math.ceil(context.total / context.limit), 1);
}
function calculateOffset(context) {
    return (context.page - 1) * context.limit;
}

function buildPaginationOptions(options) {
    const manager = createComponentOptionsManager({
        name: 'pagination'
    });
    return {
        ...options,
        busy: options.busy ?? false,
        tag: manager.buildOrFail({
            key: 'tag',
            value: options.tag,
            alt: 'ul'
        }),
        class: manager.buildOrFail({
            key: 'class',
            value: options.class,
            alt: 'pagination'
        }),
        itemTag: manager.buildOrFail({
            key: 'itemTag',
            value: options.itemTag,
            alt: 'li'
        }),
        itemClass: manager.buildOrFail({
            key: 'itemClass',
            value: options.itemClass,
            alt: 'page-item'
        }),
        linkClass: manager.buildOrFail({
            key: 'linkClass',
            value: options.linkClass,
            alt: 'page-link'
        }),
        linkActiveClass: manager.buildOrFail({
            key: 'linkActiveClass',
            value: options.linkActiveClass,
            alt: 'active'
        }),
        prevTag: manager.buildOrFail({
            key: 'prevTag',
            value: options.prevTag,
            alt: 'i'
        }),
        prevClass: manager.build({
            key: 'prevClass',
            value: options.prevClass,
            alt: []
        }),
        prevContent: manager.build({
            key: 'prevContent',
            value: options.prevContent
        }),
        nextTag: manager.buildOrFail({
            key: 'nextTag',
            value: options.nextTag,
            alt: 'i'
        }),
        nextClass: manager.build({
            key: 'nextClass',
            value: options.nextClass,
            alt: []
        }),
        nextContent: manager.build({
            key: 'nextContent',
            value: options.nextContent
        })
    };
}
function buildPagination(input) {
    const options = buildPaginationOptions(input);
    let pagesTotal = 1;
    let pageCurrent = 1;
    let offset;
    if (typeof options.offset === 'undefined') {
        if (typeof options.page !== 'undefined' && typeof options.limit !== 'undefined') {
            offset = calculateOffset({
                page: options.page,
                limit: options.limit
            });
        } else {
            offset = 0;
        }
    } else {
        offset = options.offset;
    }
    if (typeof options.total !== 'undefined' && typeof options.limit !== 'undefined') {
        pagesTotal = calculatePagesTotal({
            limit: options.limit,
            total: options.total
        });
        pageCurrent = calculatePage({
            limit: options.limit,
            offset
        });
    }
    const pagesBetween = [];
    for(let i = pageCurrent - 2; i < pageCurrent + 2; i++){
        if (i > 0 && i <= pagesTotal) {
            pagesBetween.push(i);
        }
    }
    const busy = unref(options.busy);
    const load = (page)=>{
        if (busy || page === pageCurrent) {
            return undefined;
        }
        if (isRef(options.busy)) {
            options.busy.value = true;
        }
        const data = {
            page,
            offset: calculateOffset({
                page,
                limit: options.limit
            }),
            limit: options.limit,
            total: pagesTotal
        };
        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 renderPagePrevious = ()=>{
        let content;
        if (options.prevClass || options.prevContent) {
            content = h(options.prevTag, {
                class: options.prevClass
            }, options.prevContent);
        } else {
            content = [
                pageCurrent - 1
            ];
        }
        let prevPage = [];
        if (pageCurrent > 1) {
            prevPage = [
                h(options.itemTag, {
                    class: options.itemClass
                }, [
                    h('button', {
                        class: options.linkClass,
                        disabled: options.busy,
                        onClick ($event) {
                            $event.preventDefault();
                            return load(pageCurrent - 1);
                        }
                    }, [
                        content
                    ])
                ])
            ];
        }
        return prevPage;
    };
    const renderPagesBetween = ()=>{
        const children = [];
        for(let i = 0; i < pagesBetween.length; i++){
            const node = h(options.itemTag, {
                class: options.itemClass
            }, [
                h('button', {
                    ...mergeProps({
                        ...pagesBetween[i] === pageCurrent ? {
                            class: options.linkActiveClass
                        } : {}
                    }, {
                        class: options.linkClass
                    }),
                    disabled: options.busy,
                    onClick ($event) {
                        $event.preventDefault();
                        // eslint-disable-next-line prefer-rest-params
                        return load(pagesBetween[i]);
                    }
                }, [
                    pagesBetween[i]
                ])
            ]);
            children.push(node);
        }
        return children;
    };
    const renderPageNext = ()=>{
        let nextPage = [];
        let content;
        if (options.nextClass || options.nextContent) {
            content = h(options.nextTag, {
                class: options.nextClass
            }, options.nextContent);
        } else {
            content = [
                pageCurrent + 1
            ];
        }
        if (pageCurrent < pagesTotal) {
            nextPage = [
                h(options.itemTag, {
                    class: options.itemClass
                }, [
                    h('button', {
                        class: options.linkClass,
                        disabled: options.busy,
                        onClick ($event) {
                            $event.preventDefault();
                            return load(pageCurrent + 1);
                        }
                    }, [
                        content
                    ])
                ])
            ];
        }
        return nextPage;
    };
    return h(options.tag, {
        class: options.class
    }, [
        renderPagePrevious(),
        renderPagesBetween(),
        renderPageNext()
    ]);
}

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

function install(instance, options = {}) {
    const storeManager = installStoreManager(instance);
    if (options.storeManager) {
        applyStoreManagerOptions(storeManager, options.storeManager);
    }
    instance.component('VCPagination', VCPagination);
}
var index = {
    install
};

export { VCPagination, buildPagination, buildPaginationOptions, calculateOffset, calculatePage, calculatePagesTotal, index as default, install };
//# sourceMappingURL=index.mjs.map
