<template>
  <div class="fbg-input" :tabindex="tabindex">
    <template v-if="type==='textarea'">
      <textarea ref="mainRef"  style="padding:8px;" v-model="text"  v-bind="$attrs" v-on="listeners" @blur="handleBlur" @focus="handleFocus" @keyup.enter="handleEnter" :class="'fbg-input-item ' + className" :maxlength="maxlength" :placeholder="placeholder" :style="{height: this.height,'overflow': overflow, 'min-height': minHeight+'px' }"  :disabled="disabled" />
    </template>
    <template v-else>
      <div v-if="$slots.prepend" :class="'fbg-input-prepend fbg-input-prepend-'+this.size">
        <slot name="prepend"/>
      </div>
      <template v-if="$slots.selection" >
        <slot name="selection"/>
      </template>
      <div class="fbg-input-item-box" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
        <input ref="mainRef" v-model="text" :type="type" v-bind="$attrs" @keyup="handleKeyUp" v-on="listeners" @blur="handleBlur" @focus="handleFocus" @keyup.enter="handleEnter" :style="'padding-right:'+ paddingRight+'px'" :class="'fbg-input-item ' + className" :maxlength="maxlength" :placeholder="placeholder" :disabled="disabled"/>
        <span v-if="clearable" v-show="showCloseBtn" class="fbg-input-item-remove" :style="'right: '+ (paddingRight-10) + 'px'" @click="handleClear"><i class="fbgiconfont icon-guanbishanchu" /></span>
        <i v-if="icon" :class="'fbg-input-icon fbgiconfont fbg-icon-' + icon " @click="handleIconClick"/>
      </div>
      <div v-if="$slots.append" :class="'fbg-input-append fbg-input-append-'+this.size">
        <slot name="append"/>
      </div>
    </template>
    <div :class="{'fbg-input-search-box': true, open: isShowAutoComplete, hide: !isShowAutoComplete}" @click="openStatus = true">
      <ul class="fbg-input-search-list">
        <li v-for="(item, index) in autocompleteList" :key="index" v-html="item.html" @click="handleClickSearchItem(item)" class="fbg-input-search-list-item"></li>
      </ul>
    </div>
  </div>
</template>
<script>
import { setTimeout } from 'timers';
import util from '../../utils';
import extendData from '../common/extends';
import commonExtend from '../common/commonExtend';

export default {
  name: 'FbgInput',
  mixins: [extendData, commonExtend],
  props: {
    size: {
      type: String,
      default: 'md'
    },
    disabled: {
      type: Boolean,
      default: false
    },
    icon: {
      type: String,
      default: ''
    },
    placeholder: {
      type: String,
      default: ''
    },
    value: {
      type: [String, Number],
      default: ''
    },
    type: {
      type: String,
      default: 'text'
    },
    autosize: {
      type: Boolean,
      default: false
    },
    maxlength: {
      type: Number
    },
    icon: {
      type: String,
      default: ''
    },
    clearable: {
      type: Boolean,
      default: true
    },
    check: {
      type: Boolean,
      default: true
    },
    trim: {
      type: Boolean,
      default: true
    },
    autocomplete: {
      type: Function
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(value) {
        this.text = value;
      }
    },
    text: {
      immediate: true,
      handler(value) {
        if (this.trim) {
          value = typeof value === 'string' ? value.replace(/^\s*/,'').replace(/\s*$/,'') : value;
        }
        this.updateValue(value);
      }
    }
  },
  data() {
    return {
      height: 0,
      cacheHeight: 0,
      minHeight: 54,
      overflow: 'auto',
      autocompleteList: [],
      isShowAutoComplete: false,
      openStatus: false,
      text: '',
      showCloseBtn: false,
      listeners: {},
      tabindex: 0
    };
  },
  created() {
    this.listeners = util.filterEvent(this.$listeners, ['input', 'keyup']);
  },
  mounted() {
    if (this.type === 'textarea') {
      this.height = this.minHeight + 'px';
      this.overflow = 'hidden';
    }
    document.addEventListener('click', ()=>{
      if (!this.openStatus) {
        this.isShowAutoComplete = false;
      }
      this.openStatus = false;
    });
  },
  computed: {
    paddingRight() {
      let paddingRight = 0;
      paddingRight = this.clearable ? 18: paddingRight;
      paddingRight = this.icon ? paddingRight+30: paddingRight;
      return paddingRight;
    },
    className() {
      if (this.type === 'textarea') {
        return (this.check? 'fbg-form-item-status ':'') +'fbg-input-item' + (this.disabled?' fbg-input-item-disabled':'');
      } else {
        return (this.check? 'fbg-form-item-status ':'') +'fbg-input-item-'+this.size + (this.disabled?' fbg-input-item-disabled':'') + (this.$scopedSlots.prepend||this.$scopedSlots.selection?' fbg-input-item-prepend':'')
        + (this.$scopedSlots.append?' fbg-input-item-append':'') + (this.isShowAutoComplete?' open':' hide');
      }
    }
  },
  methods: {
    focus() {
      this.$refs.mainRef.focus();
    },
    blur() {
      this.$refs.mainRef.blur();
    },
    getShowCloseBtnStatus(status) {
      return status&&this.clearable&&this.text&&!this.disabled ? true : false;
    },
    async handleKeyUp(e) {
      const value = e.target.value;
      this.$listeners.keyup && this.$listeners.keyup(e);
      if (typeof this.autocomplete === 'function' && this.type !== 'textarea') {
        this.isShowAutoComplete = true;
        try {
          const autocompleteList = await this.autocomplete(value);
          if (autocompleteList && autocompleteList.length) {
            this.autocompleteList = this.createdSearchItemHtml(autocompleteList, value);
          }
          
        } catch(e) {
          throw new Error(e);
        }
      }
    },
    handleMouseEnter() {
      this.showCloseBtn = this.getShowCloseBtnStatus(true);
    },
    handleMouseLeave() {
      this.showCloseBtn = false;
    },
    handleBlur(e) {
      this.$emit('blur', e);
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this, 'blur']);
    },
    handleFocus(e) {
      this.$emit('blur', e);
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this, 'focus']);
    },
    updateValue(value) {
      this.$emit('input', value);
      this.$emit('change', value);
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this, 'change']);
      const el = this.$refs.mainRef;
      if (this.autosize && el) {
        if (el.offsetHeight>el.scrollHeight) {
          this.height = "auto";
        } else {
          this.height = el.scrollHeight + 'px';
        }
      };
    },
    createdSearchItemHtml(list, keyword) {
      list && list.forEach(item => {
        const reg = new RegExp(keyword);
        item.html = item.label.replace(keyword, `<span class="fbg-input-search-highlight-color">${keyword}</span>`);
      });
      return list;
    },
    handleClear() {
      if (this.$emit('clear', this.value) === false) {
        return false;
      }
      this.text = '';
      this.$emit('input', '');
      this.$emit('close');
      this.dispatch('FbgFormItem', 'fbg.formItem.validate', [this, 'change']);
    },
    handleIconClick() {
      this.$emit('iconClick', this.value);
    },
    handleEnter(e) {
      this.$emit('enter', e.target.value);
    },
    handleClickSearchItem(item) {
      this.isShowAutoComplete = false;
      this.text = item.label;
      this.$emit('select', item);
    }
  }
}
</script>
<style lang="scss">
.fbg {
  &-input {
    &-search {
      &-highlight {
        &-color {
          color: #333;
        }
      }
    }
    .fbg-select-text {
      border-top-right-radius: 0px!important;
      border-bottom-right-radius: 0px!important;
      
    }
    .fbg-select {
      vertical-align: inherit!important;
      display: table-cell;
    }
  }
}
</style>
<style lang="scss" scoped>
$placeholderColor : #999;
$inputLgH : 40px;
$inputMdH : 32px;
$inputSmH : 24px;

.fbg {
  &-input {
    width: 100%;
    color: #666;
    font-size:0px;
    display: inline-table;
    position: relative;
    vertical-align: middle;
    &-search {
      &-box {
        width: 100%;
        position: absolute;
        top: 100%;
        border: 1px solid #ccc;
        border-top: 0px;
        left: 0px;
        box-sizing: border-box;
        border-bottom-left-radius: 5px;
        border-bottom-right-radius: 5px;
        transition: all 0.5s;
        overflow: hidden;
        background-color: #fff;
      }
      &-box.open {
        max-height: 300px;
        visibility: visible;
      }
      &-box.hide {
        max-height: 0px;
        visibility: hidden;
      }
      &-list {
        &-item {
          padding: 5px 10px;
          &:hover {
            background-color: #F5F6F7;
          }
        }
      }
    }
    &-icon {
      position: absolute;
      right: 10px;
      top: 0px;
      top: 50%;
      transform: translateY(-50%);
      font-size: 18px;
      font-weight: 600;
    }
    &-prepend {
      display: table-cell;
      font-size:16px;
      white-space: nowrap;
      text-align: center;
      box-sizing: border-box;
      border-radius: 5px 0px 0px 5px;
      border-left: 1px solid #ccc;
      border-top: 1px solid #ccc;
      border-bottom: 1px solid #ccc;
      padding:0px 8px;
      position: relative;
      &::after {
        content: '';
        position:absolute;
        height: 16px;
        border-left: 1px solid #ccc;
        right: -1px;
        top: 50%;
        transform: translateY(-50%);
      }
    }
    &-append {
      display: table-cell;
      width: 1px;
      font-size: 16px;
      position: relative;
      white-space: nowrap;
      vertical-align: middle;
      text-align: center;
      box-sizing: border-box;
      border-radius: 0px 5px 5px 0px;
      border-right: 1px solid #ccc;
      border-top: 1px solid #ccc;
      border-bottom: 1px solid #ccc;
      padding:0px 8px;
    }
    &-item {
      background-color: #fff; 
      border-radius:5px;
      outline: none;
      border: 1px solid #ccc;
      box-sizing: border-box;
      padding: 3px 10px;
      color: #666;
      width: 100%;
      transition: border-color .2s cubic-bezier(.645,.045,.355,1);
      &-box {
        width: 100%;
        position: relative;
        display: table-cell;
        vertical-align: middle;
      }
      &-remove {
        color: #999;
        position: absolute;
        min-width: 5px!important;
        cursor: pointer;
        top: 50%;
        transform: translateY(-50%);
        right: 8px;
        i {
          font-size: 12px;
        }
        &:hover {
          color: #3399FF;
        }
        &:focus {
          color: #3399FF;
        }
      }
      &:hover {
        border: 1px solid #999;
      }
      &:focus {
        border: 1px solid $themeColor;
        color: #333;
      }
      &-prepend {
        border-radius: 0px 5px 5px 0px; 
        border-top-left-radius: 0px!important;
        border-bottom-left-radius: 0px!important;
        border-left:1px solid rgba(0, 0, 0, 0);
      }
      &-append {
        border-radius: 5px 0px 0px 5px; 
        border-right:1px solid rgba(0, 0, 0, 0);
      }
      &-disabled {
        background-color: #F0F0F0;
        border: 1px solid #ccc;
        cursor:not-allowed;
        &:hover {
          border: 1px solid #ccc;
        }
      }
      &-lg {
        height: $inputLgH;
        line-height: $inputLgH;
        font-size: 16px;
      }
      &-md {
        height: $inputMdH;
        line-height: $inputMdH;
        font-size: 14px;      
      }
      &-sm {
        height: $inputSmH;
        line-height: $inputSmH;     
      }
    }
    &-item.open {
      border-bottom-left-radius: 0px;
      border-bottom-right-radius: 0px;
    }
    &-item.hide {
      border-bottom-left-radius: 5px;
      border-bottom-right-radius: 5px;
    }
  }
  input::-webkit-input-placeholder{
      color:$placeholderColor
  }
  input::-moz-placeholder{   /* Mozilla Firefox 19+ */
      color:$placeholderColor
  }
  input:-moz-placeholder{    /* Mozilla Firefox 4 to 18 */
      color:$placeholderColor
  }
  input:-ms-input-placeholder{  /* Internet Explorer 10-11 */ 
      color:$placeholderColor
  }
}
</style>