<template>
    <div class='v-pagination'>
        <div v-for='(item, index) in layout' :key='index'>
            <div class='v-pagination-select-box' v-if='item === "switch"'>
                <v-select 
                v-model='activePageSize' 
                :options='pageSizes'
                :disabled='disabled'
                @change='handleSizeChange'>
                </v-select>
            </div>
            <v-pages
            v-if='item === "pages"'
            ref='cpages'
            :total='total'
            :pagerCount='pagerCount'
            :pageSize='pageSize'
            v-model='cCurrentPage'
            :prependText='prependText'
            :suffixText='suffixText'
            :hideOnSinglePage='hideOnSinglePage'
            :disabled='disabled'
            :background='background'
            @prev-click='handlePrevClick'
            @next-click='handleNextClick'
            ></v-pages>
            <div :class='["v-pagination-input-box", { disabled }]' v-if='item === "jump"'>
                <span>前往</span>
                <v-input placeholder='' :disabled='disabled' v-model='jumpValue' @input='handleInput' @change='handleChange'></v-input>
                <span>页</span>
            </div>
        </div>
    </div>
</template>

<script>
import VairPagination from '../../types/pagination';
import vPages from './components/Pages';
import vSelect from '../Select/Select';
import vInput from '../Input/Input';
import { ref, computed, watchEffect, watch } from 'vue';
export default {
    name: 'pagination',
    components: {
        vPages,
        vSelect,
        vInput
    },
    props: VairPagination,
    setup (props, ctx) {
        const reg = /^\+?[1-9][0-9]*$/;
        const activePageSize = ref('');
        const oldJumpValue = ref(props.currentPage);
        const jumpValue = ref(props.currentPage);
        const cCurrentPage = ref(props.currentPage);
        const cpages = ref(null);

        const pageSizes = computed(() => {
            if (Array.isArray(props.pageSizes)) {
                let arr = [];
                props.pageSizes.forEach((item, index) => {
                    if (!reg.test(item)) {
                        throw new Error('page-sizes the item It has to be an integer greater than or equal to 1');
                    }
                    arr.push({
                        label: `${item}条 / 页`,
                        value: index,
                        number: item
                    });
                });
                return arr;
            } else {
                throw new TypeError(`page-sizes wants to receive an array, but received a ${typeof props.pageSizes}`);
            }
        });

        const handleSizeChange = (option) => {
            ctx.emit('size-change', option.number);
        };

        const handlePrevClick = (index) => {
            ctx.emit('prev-click', index);
            setJumpValue();
        };

        const handleNextClick = (index) => {
            ctx.emit('next-click', index);
            setJumpValue();
        };

        const handleInput = (value) => {
            if (!reg.test(value) && value !== '') {
                jumpValue.value = oldJumpValue.value;
            } else {
                oldJumpValue.value = value;
            }
        };

        const handleChange = (value) => {
            const max = Math.ceil(props.total / props.pageSize);
            if (value < 1) {
                jumpValue.value = 1;
                oldJumpValue.value = 1;
            } else if (value > max) {
                jumpValue.value = max;
                oldJumpValue.value = max;
            }
            cCurrentPage.value = +jumpValue.value;
        };
        
        const setJumpValue = () => {
            jumpValue.value = cCurrentPage.value;
            oldJumpValue.value = cCurrentPage.value;
        };

        watchEffect(() => {
            activePageSize.value = pageSizes.value[0].label;
        });

        watchEffect(() => {
            if (!reg.test(props.pagerCount) || props.pagerCount < 7 || props.pagerCount > 21) {
                throw new TypeError(`pager-count value of can only be an integer greater than or equal to 7 and less than or equal to 21, but received a ${props.pagerCount}`);
            }
        });

        watchEffect(() => {
            if (!reg.test(props.pageSize)) {
                throw new Error('pager-size It has to be an integer greater than or equal to 1');
            }
        });

        watch(() => props.pageSize, () => {
            setJumpValue();
        });

        watchEffect(() => {
            if (!reg.test(props.currentPage)) {
                throw new Error('current-page It has to be an integer greater than or equal to 1');
            } else {
                cCurrentPage.value = props.currentPage;
            }
        });

        watchEffect(() => {
            if (typeof props.total !== 'number' || props.total < 0) {
                throw new Error('total must be a number greater than or equal to 0');
            }
        });

        watchEffect(() => {
            ctx.emit('current-change', cCurrentPage.value);
            setJumpValue();
        });

        return {
            handleSizeChange,
            handlePrevClick,
            handleNextClick,
            handleInput,
            handleChange,
            pageSizes,
            activePageSize,
            jumpValue,
            cCurrentPage,
            cpages
        }
    }
}
</script>

<style lang='less' scoped>
.v-pagination {
    display: flex;
    align-items: center;
    .v-pagination-select-box, .v-pagination-input-box {
        width: 120px;
        /deep/.v-select, /deep/.v-input {
            min-width: 0;
        }
        /deep/.v-input {
            height: 30px;
            .v-input-box, .input {
                height: 30px;
                .suffix {
                    height: 25px;
                }
            }
        }
    }
    .v-pagination-input-box {
        display: flex;
        align-items: center;
        width: 120px;
        /deep/.v-input {
            width: 50px;
            margin: 0 6px;
            .input {
                text-indent: 0px;
                text-align: center;
            }
        }
        span {
            font-size: 14px;
        }
    }
    .disabled {
        cursor: not-allowed;
        span {
            color: #c0c4cc;
        }
    }
}
</style>