<template>
  <hn-input
    ref="numInput"
    :value="displayValue"
    :placeholder="placeholder"
    :disabled="disabled"
    @blur="handleBlur"
    @focus="handleFocus"
    @input="handleInput"
    @change="handleInputChange"/>
</template>

<script>
  import HnInput from 'heiner-ui/packages/input';
  export default {
    name: 'HnNumInput',
    components: {
      HnInput
    },
    props: {
      value: {},
      canBeNegative: {
        type: Boolean,
        default: false
      },
      equalZero: {
        type: Boolean,
        default: true
      },
      placeholder: {
        type: String,
        default: ''
      },
      disabled: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        currentValue: null,
        userInput: null
      };
    },
    computed: {
      displayValue() {
        const { userInput, currentValue } = this;
        if (userInput !== null) {
          return userInput;
        }
        return currentValue;
      }
    },
    watch: {
      value: {
        immediate: true,
        handler(value) {
          const newVal = value === null ? value : Number(value);
          if (newVal !== null) {
            if (isNaN(newVal)) {
              return;
            }
          }
          this.currentValue = newVal;
          this.userInput = null;
          this.$emit('input', newVal);
        }
      }
    },
    methods: {
      handleBlur(event) {
        this.$emit('blur', event);
        const { value } = event.target;
        const { canBeNegative } = this;
        if (canBeNegative && value === '-') {
          this.setCurrentValue(null);
        }
      },
      handleFocus(event) {
        this.$emit('focus', event);
      },
      setCurrentValue(newVal) {
        const oldVal = this.currentValue;
        if (oldVal === newVal) return;
        this.userInput = null;
        this.$emit('input', newVal);
        this.$emit('change', newVal, oldVal);
        this.currentValue = newVal;
      },
      handleInput(value) {
        this.userInput = this.clearNoNum(value);
      },
      handleInputChange(value) {
        let newVal = value === '' ? null : Number(value);
        const { equalZero } = this;
        if (!equalZero && newVal === 0) {
          newVal = null;
        }
        if (!isNaN(newVal) || value === '') {
          this.setCurrentValue(newVal);
        } else if (['-', '-0'].includes(value)) {
          this.setCurrentValue(value);
        }
        this.userInput = null;
      },
      clearNoNum(value) {
        const { canBeNegative } = this;
        let val = value;
        if (!canBeNegative) {
          val = val.replace(/[^\d.]/g, ''); // 清除“数字”、“.”以外的字符
          val = val.replace(/\.{2,}/g, '.'); // 只保留第一个. 清除多余的
          val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); // 保证.只出现一次，而不能出现两次以上
          if (val.indexOf('.') === 0) {
            val = `0${val}`;
          }
          val = val.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');// 只能输入两个小数
          if (val.indexOf('.') < 0 && val !== '') { // 以上已经过滤，此处控制的是如果没有小数点，首位不能为类似于 01、02的金额
            val = parseFloat(val);
          }
        } else {
          val = val.replace(/[^-\d.]/g, ''); // 清除负号、“数字”、“.”以外的字符
          val = val.replace(/\.{2,}/g, '.');
          val = val.replace(/-{2,}/g, '-');
          val = val.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.');
          val = val.replace('-', '$#$').replace(/-/g, '').replace('$#$', '-');
          if (val.indexOf('-') > 0) {
            val = val.replace(/-/, '');
          }
          if (val === '-') return val;
          if (val.indexOf('.') === 0) {
            val = `0${val}`;
          } else if (val.indexOf('-.') === 0) {
            val = '-0.';
          }
          val = val.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
          if (val.indexOf('.') < 0 && !['', '-', '-0'].includes(val)) {
            val = parseFloat(val);
          }
        }
        return val;
      }
    }
  };
</script>
