<template>
    <view
        :class="{
            'm-inputnum--disable': disable,
            'm-border': !miniBorder,
        }"
        class="m-inputnum c-flex-row"
        :style="inputNumStyle"
    >
        <view
            class="m-control cut c-span2 c-color-gray"
            :style="opStyle"
            @tap="cut"
        >
            -
        </view>
        <input
            v-if="inputAble"
            v-model="number"
            type="number"
            :selection-start="0"
            :selection-end="number.length"
            class="m-input c-span8 c-color c-font-small"
            :style="inputStyle"
            :disable="disable"
            @blur="blur"
        >
        <view
            v-else
            class="m-input c-span8 c-color c-font-small"
            :style="inputStyle"
        >
            {{ number }}
        </view>
        <view
            class="m-control add c-span2 c-color-gray"
            :style="opStyle"
            @tap="add"
        >
            +
        </view>
        <!-- 细边框 -->
        <view
            v-if="miniBorder"
            :class="miniBorder ? 'mini-border' : ''"
        />
    </view>
</template>

<script>
import {throttle} from '@utils/core';
/**
 * @file inputnum
 * @author zhangeryi@baidu.com
 */
export default {
    config: {
        component: true
    },
    options: {
        addGlobalClass: true
    },
    props: {
        num: {
            type: [String, Number],
            default: 1
        },
        max: {
            type: [Number, String],
            default: 5
        },
        mix: {
            type: [Number, String],
            default: 1
        },
        errMaxInfo: {
            type: String,
            default: '不能再大了~'
        },
        errMinInfo: {
            type: String,
            default: '不能再小了~'
        },
        inputAble: {
            type: Boolean,
            default: true
        },
        disable: {
            type: Boolean,
            default: false
        },
        inputNumStyle: {
            type: Object
        },
        // + -操作符的样式
        opStyle: {
            type: Object
        },
        //  input框的样式
        inputStyle: {
            type: Object
        },
        // 是否使用细边框
        miniBorder: {
            type: Boolean,
            default: false
        },
        lock: {
            type: Boolean,
            default: false
        }
    },
    data() {
        this.addFn = null;
        this.cutFn = null;
        return {
            number: (this.num && this.num.toString()) || 0,
            oldValue: '',
            validate: true
        };
    },
    watch: {
        num(newVal, oldVal) {
            if (newVal !== oldVal) {
                this.number = this.num.toString();
            }
        },
        number(newVal, oldValue) {
            // 发现二次输入时会有问题所以需要视图更新后检查
            this.$mpUpdated().then(() => {
                this.checkNum(newVal, oldValue);
                this.oldValue = oldValue;
            });
        }
    },
    created() {
        this.number = this.num && this.num.toString();
    },
    methods: {
        add() {
            if (!this.addFn) {
                this.addFn = throttle(this._add, 600);
            }
            if (!this.lock) {
                this.addFn();
            }
        },
        cut() {
            if (!this.cutFn) {
                this.cutFn = throttle(this._cut, 600);
            }
            if (!this.lock) {
                this.cutFn();
            }
        },
        _add() {
            if (+this.number === +this.max) {
                return this.$api.showToast({
                    icon: 'none',
                    duration: 1000,
                    title: this.errMaxInfo
                });
            }
            this.number = (+this.number + 1).toString();
        },
        _cut() {
            if (+this.number === +this.mix) {
                return this.$api.showToast({
                    icon: 'none',
                    duration: 1000,
                    title: this.errMinInfo
                });
            }
            this.number = (+this.number - 1).toString();
        },
        blur(e) {
            // 失去焦点时再校验一遍
            if (!this.validate) {
                this.checkNum(e.detail.value, this.oldValue, true);
                // 还是不行就改为oldValue
                if (!this.validate) {
                    this.number = this.oldValue;
                }
            }
        },
        // check 是否需要强制校验
        checkNum(newVal, oldValue, check) {
            this.validate = false;
            // 默认不校验空值，为了允许删除后修改
            if (newVal !== '' || check) {
                // 去掉非零字符和开头的零
                newVal = newVal.toString().replace(/\D/g, '').replace(/^0+/, '');
                // 检查大小范围
                if (+newVal > +this.max) {
                    newVal = +this.max;
                    this.$api.showToast({
                        icon: 'none',
                        duration: 1000,
                        title: this.errMaxInfo
                    });
                }
                // 无库存时num为0、this.disable为true, 此时不修改为mix
                if (!this.disable && +newVal < +this.mix) {
                    newVal = +this.mix;
                    this.$api.showToast({
                        icon: 'none',
                        duration: 1000,
                        title: this.errMinInfo
                    });
                }
                this.number = newVal.toString();
                this.validate = true;
                if (+newVal !== +oldValue && +this.num !== +newVal) { // props传的num不要再触发change，会导致死循环
                    this.$emit('change', +this.number);
                }
            } else {
                this.validate = false;
            }
        }
    }
};
</script>
<style lang="less" scoped>
.m-border {
    border: 1px solid #f1f1f1;
    border-radius: 3px;
}

.mini-border {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;
    height: 200%;
    transform: scale(0.5);
    transform-origin: left top;
    box-sizing: border-box;
    border: 1px solid #e0e0e0;
    border-radius: 0.12rem;
    z-index: 0;
}

.m-inputnum {
    text-align: center;
    align-items: center;
    height: 20px;
    line-height: 20px;
    position: relative;

    &--disable {
        &::before {
            content: '';
            display: block;
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            background: #fff;
            opacity: 0.8;
            z-index: 2;
        }
    }

    .m-control {
        z-index: 1;
        width: 26px;
        flex: none;

        &.add {
            border-left: 1px solid #f1f1f1;
        }

        &.cut {
            border-right: 1px solid #f1f1f1;
        }
    }

    .m-input {
        z-index: 1;
        text-align: center;
        height: 20px;
        font: 12px/20px Arial, Helvetica, sans-serif;
        outline: none;
    }
}
// 去掉chrome表单自动填充样式
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px white inset;
}

input[type='text']:focus,
input[type='password']:focus,
textarea:focus {
    -webkit-box-shadow: 0 0 0 1000px white inset;
}
</style>
