<template>
  <div class="input-unit" :id="maxlengthAppendId">
    <InputNumber v-if="type === 'number'"
      :id="numberId"
      :placeholder="placeholder"
      :size="size"
      :precision="precision"
      v-model="CurrentVal"
      :disabled="disabled ? true : false"
      :active-change="false"
      @on-blur="blur"
      @on-focus="focus"
    ></InputNumber>
    <i-input v-else
      :placeholder="placeholder"
      :maxlength="maxlength"
      :show-word-limit="showWordLimit"
      :size="size"
      :type="type"
      :rows="rows"
      :autosize="autoSize"
      v-model="CurrentVal"
      :disabled="disabled ? true : false"
      :element-id="textareaId"
      @on-enter="enter"
      @on-blur="blur"
      @on-focus="focus"
    >
    <template v-if="append" #append>
      <span>{{ append }}</span>
    </template>
    <template v-if="prepend" #prepend>
      <span>{{ prepend }}</span>
    </template>
  </i-input>
    <div class="unit-text">{{unit}}</div>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator";
import { Subject } from "rxjs";
import { debounceTime, distinctUntilChanged } from "rxjs/operators";

@Component({})
export default class InputBox extends Vue {
  
  /**
   * 双向绑定值
   * @type {any}
   * @memberof InputBox
   */
  @Model("change") readonly itemValue?: any;

  /**
     * 生命周期 （多行文本十行高度问题）
     * @type {any}
     * @memberof InputBox
     */
    public created() {
        if(this.editorType && this.editorType == "TEXTAREA_10") {
            this.rows = 10;
        }
        if(this.minRows){
          this.autoSize.minRows = this.minRows;
        }
        if(this.maxRows){
          this.autoSize.maxRows = this.maxRows;
        }
    }

  /**
   * 生命周期 （多行文本十行高度问题）
   * @type {any}
   * @memberof InputBox
   */
  public mounted(){
    this.addEvent();
    if(this.textareaId){
      let textarea :any= document.getElementById(this.textareaId);
      if(textarea){
        textarea.style=this.textareaStyle;
      }
    }
    if(this.showWordLimit && (this.append || this.prepend)){
      this.setAppendStyle();
    }
  }

  /**
   * 单位
   * @type {String}
   * @memberof InputBoxUnit
   */
  @Prop() public unit?: string;


  /**
   * 多行文本十行 特殊参数样式（模型高度自带）
   * @type {String}
   * @memberof InputBoxUnit
   */
  @Prop() public textareaStyle?: string;

  /**
   * 多行文本十行 特殊参数id（模型高度自带）
   * @type {String}
   * @memberof InputBoxUnit
   */
  @Prop() public textareaId?: string;
  /**
   * 大小
   * @type {String}
   * @memberof InputBoxUnit
   */
  @Prop() public size?: string;

   /**
     * 编辑器样式
     * @type {String}
     * @memberof InputBoxUnit
     */
    @Prop() public editorType?: string;

    /**
     * 文本行数
     * @type {String}
     * @memberof InputBoxUnit
     */
    public rows: number = 2;

  /**
   * placeholder值
   * @type {String}
   * @memberof InputBox
   */
  @Prop() public placeholder?: string;

  /**
   * 是否禁用
   * @type {boolean}
   * @memberof InputBox
   */
  @Prop() public disabled?: boolean;

  /**
   * 属性类型
   *
   * @type {string}
   * @memberof InputBox
   */
  @Prop() public type?: string;

  /**
   * 精度
   *
   * @type {number}
   * @memberof InputBox
   */
  @Prop({default: 0}) public precision?: number;

  /**
   * 输入内容最大长度
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public maxlength?: number;

   /**
   * 输入内容前缀
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public prepend?: any;

   /**
   * 输入内容后缀
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public append?: any;

  /**
   * 是否显示输入内容最大长度
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public showWordLimit?: boolean;

  /**
   * 多行文本类型下最小行数
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public minRows?: number;

  /**
   * 多行文本类型下最大行数
   *
   * @type {string}
   * @memberof InputBox
   */
   @Prop() public maxRows?: number;

   /**
   * 多行文本行数
   *
   * @type {string}
   * @memberof InputBox
   */
  public autoSize: any = {};

  /**
   * 数值框numberId
   */
  public numberId :string= this.$util.createUUID();

  //当同时存在最长长度与后缀词时，input的id
  public maxlengthAppendId: string = this.$util.createUUID();

  /**
   * 当前值
   *
   * @memberof InputBox
   */
  get CurrentVal() {
    if(Object.is(this.type, 'number') && this.itemValue && !isNaN(this.itemValue)){
      return Number(Number(this.itemValue).toFixed(this.precision));
    }else{
      return this.itemValue;
    }
  }

  /**
   * 值变化
   *
   * @memberof InputBox
   */
  set CurrentVal(val: any) {
    let _data: any = val;
    if (Object.is(this.type, "number") && val && !isNaN(val)) {
      try {
        _data = isNaN(Number(val)) ? null : Number(val);
      } catch (error) {}
    }
    if (Object.is(_data, "")) {
      _data = null;
    }
    this.$emit("change", _data);
  }

  /**
   * 回车事件
   *
   * @param {*} $event
   * @memberof InputBox
   */
  @Emit()
  public enter($event: any) {
    if (!$event || $event.keyCode !== 13) {
      return;
    }
    return $event;
  }

  /**
   * 输入框失焦
   * 
   * @memberof InputBox
   */
  public blur(){
    this.$emit('blur',this.itemValue)
  }
  
  /**
   * 输入框聚焦
   * 
   * @memberof InputBox
   */
  public focus(){
    this.$emit('focus',this.itemValue)
  }

  /**
   * 给数值框中的箭头按钮添加事件
   * 
   * @memberof InputBox
   */
  public addEvent(){
    if(Object.is(this.type, "number")){
      // 整个页面渲染完之后再去执行
      this.$nextTick(() => {
        let inputNumber :any = document.getElementById(this.numberId);
        let handlerWrap :any = inputNumber.firstElementChild;
        handlerWrap.onmouseover=()=>{
          inputNumber.style.paddingRight="15px";
          inputNumber.style.transition="all 0.2s linear";
        }
        handlerWrap.onmouseout=()=>{
          inputNumber.style.paddingRight="0px";
        }
      });
    }
  }

  /**
   * 当同时设置了前缀(或后缀词)与显示最长长度时，动态重新设置样式，iview原本的样式有异常
   * 
   * @memberof InputBox
   */
   public setAppendStyle() {
        if (Object.is(this.type, 'text') || Object.is(this.type, 'textarea')) {
            this.$nextTick(() => {
                let input: any = document.getElementById(this.maxlengthAppendId);
                if (input) {
                    let appendEle = input.querySelector('.ivu-input-group-append');
                    let maxlengthEle = input.querySelector('.ivu-input-word-count');
                    let unitEle = input.querySelector('.unit-text');
                    let appendEleWidth = null;
                    let maxlengthEleWidth = null;
                    if (appendEle) {
                        appendEleWidth = window.getComputedStyle(appendEle).getPropertyValue('width');
                    }
                    if (maxlengthEle) {
                        maxlengthEleWidth = window.getComputedStyle(maxlengthEle).getPropertyValue('width');
                    }
                    const setEleStyle = (ele: any) => {
                        ele.style.paddingRight = '5px';
                        ele.style.marginRight = '1px';
                        ele.style.zIndex = '10';
                    };
                    if (appendEleWidth && maxlengthEleWidth) {
                        const width = Number(appendEleWidth.slice(0,-2)) + Number(maxlengthEleWidth.slice(0,-2));
                        maxlengthEle.style.right = appendEleWidth;
                        unitEle.style.right = width + 'px';
                    } else if (appendEleWidth) {
                        unitEle.style.right = appendEleWidth;
                    } else if (maxlengthEleWidth) {
                        maxlengthEle.style.right = maxlengthEleWidth;
                    }
                    setEleStyle(unitEle);
                    setEleStyle(maxlengthEle);
                    if (this.prepend) {
                        maxlengthEle.style.zIndex = '10';
                    }
                }
            });
        }
    }


}
</script>

<style lang='less'>
@import "./input-box.less";
</style>