<!-- @slot  prefix-->
<!-- @slot  suffix-->
<!-- @slot  prefixIcon-->
<!-- @slot  suffixIcon-->

<script>
import Icon from '../icon';
import Emitter from 'utils-lib/dist/emitter';
const name = 'hive-input';

const noop = () => {};

export default {
  name: name,
  components: {
    Icon
  },
  mixins: [Emitter],
  inheritAttrs: false,
  props: {
    /**
     * 前缀，支持同名slot
     */
    prefix: { type: String },
    /**
     * 后缀，支持同名slot
     */
    suffix: { type: String },
    /**
     * 前缀Icon，支持同名slot
     */
    prefixIcon: { type: String },
    /**
     * 后缀Icon，支持同名slot
     */
    suffixIcon: { type: String },
    /**
     * 尺寸
     *
     * @member default | small
     */
    size: { type: String, default: 'default', validator(v) { return ['default', 'small'].indexOf(v) > -1; } },
    /**
     * 是否为错误状态
     */
    error: { type: Boolean, default: false },
    /**
     * 禁用
     */
    disabled: { type: Boolean, default: false },
    /**
     * 是否聚焦
     */
    focused: { type: Boolean },
    /**
     * 值
     *
     * @model
     */
    value: { type: [String, Number] },
    /**
     * 是否显示清除按钮
     */
    allowClear: { type: Boolean, default: false },
    /**
     * 获取原生input Dom
     * @ignore
     */
    getInput: { type: Function }
  },
  data() {
    return {
      curFocused: this.$props.focused,
      curValue: this.$props.value
    };
  },
  computed: {
    hasPrefix() {
      return this.$scopedSlots.prefix || this.prefix;
    },
    hasSuffix() {
      return this.$scopedSlots.suffix || this.suffix;
    },
    hasPrefixIcon() {
      return this.$scopedSlots.prefixIcon || this.prefixIcon;
    },
    hasSuffixIcon() {
      if (this.curValue && !this.disabled && this.allowClear) return 'circle_clear';
      return this.$scopedSlots.suffixIcon || this.suffixIcon;
    },
    className() {
      return [
        'hive-input',
        `hive-input--size-${this.size}`,
        {
          'hive-input--status-error': this.error,
          'hive-input--disabled': this.disabled,
          'hive-input--focused': this.curFocused,
          'hive-input--with-prefix': this.hasPrefix,
          'hive-input--with-suffix': this.hasSuffix
        }
      ];
    },
    inputWrapClassName() {
      return [
        'hive-input__input',
        {
          'hive-input__input--status-error': this.error,
          'hive-input__input--focused': this.curFocused,
          'hive-input__input--disabled': this.disabled,
          'hive-input__input--prefixicon': this.hasPrefixIcon,
          'hive-input__input--suffixicon': this.hasSuffixIcon
        }
      ];
    }
  },
  watch: {
    value(v) {
      this.curValue = v;
    }
  },
  mounted() {
    this.getInput && this.getInput(this.$refs.refInputElem);
  },
  created() {
    this.blurT = null;
  },
  beforeMount() {
    clearTimeout(this.blurT);
  },
  methods: {
    onChange(e) {
      /**
       * change 回调
       *
       * @param {Object} e 事件对象
       */
      this.$emit('change', e);
    },
    onInput(e) {
      this.curValue = e.target.value;
      /**
       * input 回调
       *
       * @model
       * @param {Object} value 输入值
       */
      this.$emit('input', this.curValue);
    },
    onFocus(e) {
      this.curFocused = true;
      /**
       * 聚焦回调
       *
       * @param {Object} e 事件对象
       */
      this.$emit('focus', e);
    },
    onBlur(e) {
      this.curFocused = false;
      this.$emit('blur', e);
      this.dispatch('hive-form-item', 'form.blur', this.curValue);
    },
    onInputClick() {
      this.$refs.refInputElem && this.$refs.refInputElem.focus();
    },
    onClear(e) {
      e.stopPropagation();
      this.curValue = '';
    },
    forceUpdateCurValue(v) {
      this.curValue = v;
    }
  },
  render(h) {
    const {
      inputPrefixRaw,
      inputPrefix,
      inputSuffix } = this.$scopedSlots;

    const {
      hasPrefixIcon,
      hasSuffixIcon,
      hasPrefix,
      hasSuffix } = this;

    const {
      keydown = noop,
      keyup = noop,
      keypress = noop,

      change,
      input: inputEvent,
      focus,
      blur,

      ...othersEvent } = this.$listeners;

    const {
      placeholder,
      type,
      readonly,
      name: nameAttr } = this.$attrs;

    const inputEventFromProps = { keydown, keyup, keypress };

    const inputAttrsFromProps = { placeholder, readonly, readOnly: readonly, disabled: this.disabled };

    const inputRaw = h(
      'input',
      {
        class: 'hive-input__input-input',
        attrs: {
          type: type || 'text',
          name: nameAttr,
          value: this.curValue,
          ...inputAttrsFromProps
        },
        domProps: {
          value: this.curValue
        },
        ref: 'refInputElem',
        on: {
          input: this.onInput,
          blur: this.onBlur,
          change: this.onChange,
          focus: this.onFocus,
          ...inputEventFromProps
        }
      }
    );

    let defaultSuffixIcon = <Icon icon={hasSuffixIcon} />;

    if (hasSuffixIcon === 'circle_clear') {
      defaultSuffixIcon = <Icon class="hive-input__input-close" role="button" tabIndex={0} icon={hasSuffixIcon} onClick={this.onClear} />;
    }

    const input = (
      <div class={this.inputWrapClassName} onClick={this.onInputClick}>
        {
          hasPrefixIcon ? <span class="hive-input__input-icon hive-input__input-icon--prefix">{typeof hasPrefixIcon === 'function' ? hasPrefixIcon() : <Icon icon={hasPrefixIcon} />}</span> : null
        }
        {
          inputPrefix && <span ref="refInputPrefix" class="hive-input__input-prefix">{inputPrefix()}</span>
        }
        {
          inputPrefixRaw && inputPrefixRaw()
        }
        {inputRaw}
        {
          inputSuffix && <span ref="refInputSuffix" class="hive-input__input-suffix">{inputSuffix()}</span>
        }
        {
          hasSuffixIcon ? <span class="hive-input__input-icon hive-input__input-icon--suffix">{typeof hasSuffixIcon === 'function' ? hasSuffixIcon() : defaultSuffixIcon}</span> : null
        }
      </div>
    );

    return h(
      'div',
      {
        class: this.className,
        on: { ...othersEvent }
      },
      [
        hasPrefix ? <span class="hive-input__prefix">{typeof hasPrefix === 'function' ? hasPrefix() : hasPrefix}</span> : null,
        input,
        hasSuffix ? <span class="hive-input__suffix">{typeof hasSuffix === 'function' ? hasSuffix() : hasSuffix}</span> : null
      ]
    );
  }
};
</script>
