<script>
import { componentMixin, createComponentName } from '../_utils/component.js';
import Icon from '../Icon';
import Select from '../Select';

export default {
    name: createComponentName('pagination'),
    mixins: [componentMixin],
    props: {
        // 分页布局
        layout: {
            // - < [] > * ->
            type: String,
            default: '< [] >'
        },
        // 当前页数
        num: {
            type: Number,
            default: 1
        },
        // 每页条数
        pageSize: {
            type: Number,
            default: 20
        },
        // 数据总数
        total: {
            type: Number,
            default: 0
        },
        // 每页可以显示多少条
        sizes: {
            type: Array,
            default: () => [20, 40, 60]
        },
        // 页数最多显示多少条
        pagerCount: {
            type: Number,
            default: 7,
        },
        // 自定义渲染 可用于SEO
        renderItem: {
            type: Function
        },
    },
    computed: {
        pages() {
            return Math.ceil(this.total / this.pageSize);
        },
        numbers() {
            if (this.total <= this.pageSize) return [1];
            const pagerCount = this.pagerCount;

            const currentPage = Number(this.num);
            const pageCount = Number(this.pages);
            let showPrevMore = false;
            let showNextMore = false;


            if (pageCount > pagerCount) {
                if (currentPage > pagerCount - 3) {
                    showPrevMore = true;
                }
                if (currentPage < pageCount - 3) {
                    showNextMore = true;
                }
            }

            const array = [];
            if (showPrevMore && !showNextMore) {
                const startPage = pageCount - (pagerCount - 2);
                for (let i = startPage; i < pageCount; i += 1) {
                    array.push(i);
                }
            }
            else if (!showPrevMore && showNextMore) {
                for (let i = 2; i < pagerCount; i += 1) {
                    array.push(i);
                }
            }
            else if (showPrevMore && showNextMore) {
                const offset = Math.floor(pagerCount / 2) - 1;
                for (let i = currentPage - offset; i <= currentPage + offset; i += 1) {
                    array.push(i);
                }
            }
            else {
                for (let i = 2; i < pageCount; i += 1) {
                    array.push(i);
                }
            }

            if (showNextMore) {
                array.push('>>', this.pages);
            }
            else {
                array.push(this.pages);
            }

            if (showPrevMore) {
                array.unshift(1, '<<');
            }
            else {
                array.unshift(1);
            }
            return array;
        }
    },
    methods: {
        changeSize(value) {
            if (value === this.pageSize) return;

            this.$emit('update:size', value);
            this.$emit('change', this.num, value);
        },

        changeNum(value) {
            if (value === this.num) return;
            let num = value > this.pages ? this.pages : value;
            num = num > 0 ? num : 1;
            this.$emit('update:num', num);
            this.$emit('change', num, this.pageSize);
        },

        renderPrev() {
            let content = (
                <div
                    onClick={() => this.changeNum(this.num - 1)}
                    class={this.bem('number', {
                        'prev': true,
                        disabled: this.num - 1 < 1
                    })}
                >
                    <Icon name="arrow-left"></Icon>
                </div>
            );

            if (this.renderItem && this.num - 1 >= 1) {
                return this.renderItem(this.num - 1, 'prev', content);
            }

            return content;
        },

        renderNext() {
            let content = (
                <div
                    class={this.bem('number', {
                        'next': true,
                        disabled: this.num + 1 > this.pages
                    })}
                    onClick={() => this.changeNum(this.num + 1)}
                >
                    <Icon name="arrow-right"></Icon>
                </div>
            );

            if (this.renderItem && this.num - 1 >= 1) {
                return this.renderItem(this.num + 1, 'next', content);
            }

            return content;
        },

        renderPager() {
            return (
                <Select
                    class={this.bem('pager')}
                    value={this.pageSize}
                    options={this.sizes.map(size => ({ value: size, label: `每页${size}条` }))}
                    onChange={this.changeSize}
                />
            );
        },

        renderTotal() {
            return <span class={this.bem('total')}>共<em>{this.total}</em>条</span>;
        },

        renderJump() {
            return (
                <span class={this.bem('jump')}>
                    到
                    <gd-input
                        style={{ width: '60px' }}
                        onEnter={e => this.changeNum(Number(e.target.value))}
                    ></gd-input>
                    页
                </span>
            );
        },

        renderNumber(i) {
            let body = i;
            if (i === '<<') {
                body = '•••';
            }
            else if (i === '>>') {
                body = '•••';
            }

            const isNumber = typeof i === 'number';

            let content = (
                <div
                    class={this.bem('number', { 'active': i === this.num, ellipsis: !isNumber })}
                    onClick={() => isNumber && this.changeNum(i)}
                >
                    {body}
                </div>
            );

            if (this.renderItem) {
                return this.renderItem(i, isNumber ? 'number' : 'ellipsis', content);
            }

            return content;
        },

        renderNumbers() {
            return (
                <div role="ul" class={this.bem('numbers')} unselectable="unselectable">
                    {this.numbers.map(value => this.renderNumber(value))}
                </div>
            );
        }
    },
    render() {
        if (this.total < this.pageSize && this.num === 1) return null;

        const types = this.layout.split(' ').filter(value => value);
        const components = types.map((type) => {
            switch (type) {
                case '-':
                    return this.renderPager();
                case '[]':
                    return this.renderNumbers();
                case '<':
                    return this.renderPrev();
                case '>':
                    return this.renderNext();
                case '*':
                    return this.renderTotal();
                case '->':
                    return this.renderJump();
                default:
                    break;
            }
            return null;
        });

        return (
            <div class="gd-pagination">
                {components}
            </div>
        );
    }
};
</script>

<style lang="less">
@import "../_styles/base.less";

.@{pagination} {
    display: flex;
    align-items: center;
    justify-content: center;
    user-select:none;

    a {
        display: inline-block;
        text-decoration: none;
    }

    &__total {
        em {
            margin: 0 4px;
        }
    }

    * + &__total {
        margin-left: 8px;
    }
    &__total + * {
        margin-left: 8px;
    }

    &__jump {
        display: flex;
        align-items: center;

        .gd-input {
            margin: 0 4px;
            width: 30px;
            height: 40px;
        }
    }

    &__pager.@{select} {
        width: 115px;
        height: 40px;
        margin: 0 @margin-xsm / 2;
    }

    &__numbers {
        margin: 0;
        padding: 0;
    }

    &__number {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        background: #fff;
        border: 1px solid @border-color-default;
        color: @color-body;
        height: 40px;
        min-width: 40px;
        text-align: center;
        vertical-align: top;
        cursor: pointer;
        margin: 0 @margin-xsm / 2;

            &--prev,
            &--next {
                width: 70px;
                height: 40px;
            }

            &--disabled {
                color: @color-disable;
                cursor: default;
            }

            &--ellipsis {
                border: none;
                cursor: default;
                color: rgba(0,0,0,0.25);
                letter-spacing: 2px;
            }
    }

    &__number:hover:not(.@{pagination}__number--disabled):not(.@{pagination}__number--active):not(.@{pagination}__number--ellipsis){
        color: @color-primary;
    }

    &__number--active {
        background-color: @color-primary;
        border-radius: @border-radius-base;
        color: white;
        cursor: default;
    }
}
</style>
