<template>
  <div class="el-area-select">
    <div class="el-area-select__tags" @click="handleFocus" ref="tags">
      <span v-if='collapseTags && value.length > 0'>
        <el-tag
          :closable="!selectDisabled"
          :size="collapseTagSize"
          type="info"
          @close="deleteTag($event, value[0])"
          disable-transitions>
          <span class="el-area-select__tags-text">{{ value[0][actualProps.label] }}</span>
        </el-tag>
        <el-tag
          v-if="value.length > 1"
          :closable="false"
          :size="collapseTagSize"
          type="info"
          disable-transitions>
          <span class="el-area-select__tags-text">+ {{ value.length - 1 }}</span>
        </el-tag>
      </span>
      <span v-else>
        <el-tag
          v-for="item in value"
          ref="lastTag"
          :key="item[actualProps.value]"
          :closable="!selectDisabled"
          :size="collapseTagSize"
          type="info"
          @close="deleteTag($event, item)"
          disable-transitions>
          <span class="el-area-select__tags-text">{{ item[actualProps.label] }}</span>
        </el-tag>
      </span>
      <el-tag
        ref="trigger"
        :class="{ 'trigger': true, 'disabled': selectDisabled}"
        :size="collapseTagSize"
        :type="selectDisabled ? 'info' : ''"
        @click="choose">
        点击选择
      </el-tag>
    </div>
    <el-input
      ref="reference"
      type="input"
      :placeholder="propPlaceholder"
      :autocomplete="autocomplete"
      :disabled="selectDisabled"
      :validate-event="false"
      :class="{ 'is-focus': softFocus }"
      :readonly="true"
      :autosize="true"
      @focus="softFocus = true"
      @blur="softFocus = false"
    ></el-input>
  </div>
</template>

<script>
import ElTag from '@ued_fpi/element-ui/packages/tag';
import Focus from '@ued_fpi/element-ui/src/mixins/focus';
import Locale from '@ued_fpi/element-ui/src/mixins/locale';
import Emitter from '@ued_fpi/element-ui/src/mixins/emitter';
import ElInput from '@ued_fpi/element-ui/packages/input';
import { addResizeListener, removeResizeListener } from '@ued_fpi/element-ui/src/utils/resize-event';
import { valueEquals } from '@ued_fpi/element-ui/src/utils/util';
const defaultProps = {
  label: 'label',
  value: 'value'
};
export default {
  name: 'ElAreaSelect',
  componentName: 'ElAreaSelect',
  mixins: [Emitter, Locale, Focus('reference')],
  inject: {
    elForm: {
      default: ''
    },

    elFormItem: {
      default: ''
    }
  },
  provide() {
    return {
      'areaSelect': this
    };
  },
  components: {ElTag, ElInput},
  props: {
    value: Array,
    disabled: {
      type: Boolean,
      default: false
    }, // 是否禁用
    props: {
      type: Object,
      default() {
        return {};
      }
    },
    collapseTags: {
      type: Boolean,
      default: false
    }, // 多选时是否将选中值按文字的形式展示
    autocomplete: {
      type: String,
      default: 'off'
    },
    placeholder: {
      type: String,
      default: '请选择'
    }
  },
  watch: {
    // 监听值的变化，比较值前后是否有改变，是否需要触发form表单的change校验
    value(val, oldVal) {
      this.resetInputHeight();
      if (!valueEquals(val, oldVal)) {
        this.dispatch('ElFormItem', 'el.form.change', val);
      }
    }
  },
  data() {
    return {
      softFocus: false, // 当前是否聚焦
      initialInputHeight: 0 // 每一行的基础敢赌
    };
  },
  computed: {
    actualProps() {
      return {
        ...defaultProps,
        ...this.props
      };
    },
    // 是否可选择
    selectDisabled() {
      return this.disabled || (this.elForm || {}).disabled;
    },
    // form表单控件大小
    _elFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize;
    },
    // 实际控件大小
    selectSize() {
      return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
    },
    // 控件大小
    collapseTagSize() {
      return ['small', 'mini'].indexOf(this.selectSize) > -1
        ? 'mini'
        : 'small';
    },
    // 控件的占位符
    propPlaceholder() {
      if (this.value.length > 0) return '';
      return typeof this.placeholder !== 'undefined' ? this.placeholder : this.t('el.select.placeholder');
    }
  },
  mounted() {
    // 基础一行高度
    const reference = this.$refs.reference;
    if (reference && reference.$el) {
      const sizeMap = {
        medium: 36,
        small: 32,
        mini: 28
      };
      const input = reference.$el.querySelector('input');
      this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize];
    }
    // 重置高度
    this.resetInputHeight();
    // 添加dom高度变化监听
    addResizeListener(this.$el, this.handleResize);
  },
  methods: {
    /**
     * 删除其中一项
    */
    deleteTag(event, tag) {
      const key = this.actualProps.value;
      let index = this.value.findIndex(item => item[key] === tag[key]);
      if (index > -1 && !this.selectDisabled) {
        const value = this.value.slice();
        value.splice(index, 1);
        this.$emit('input', value);
        this.$emit('remove-tag', tag.value);
      }
      event.stopPropagation();
    },
    // 聚焦事件
    handleFocus() {
      this.$refs.reference.focus();
    },
    /**
     * dom宽高变化
    */
    handleResize() {
      // this.resetInputWidth();
      this.resetInputHeight();
    },
    /**
     * 重置宽度
    */
    resetInputWidth() {
      this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
    },
    /**
     * 重置高度
    */
    resetInputHeight() {
      if (this.collapseTags) return;
      this.$nextTick(() => {
        if (!this.$refs.reference) return;
        const tags = this.$refs.tags;
        const tagsHeight = tags ? Math.round(tags.getBoundingClientRect().height) : 0;
        const sizeInMap = this.initialInputHeight + 2;
        this.$refs.reference.$el.style.height = this.value.length === 0
          ? sizeInMap + 'px'
          : Math.max(
            tags ? (tagsHeight + (tagsHeight > sizeInMap ? 6 : 2)) : 0,
            sizeInMap
          ) + 'px';
      });
    },
    /**
     * 点击`点击选择`按钮触发
    */
    choose() {
      if (this.selectDisabled) return;
      this.$emit('choose');
    }
  },
  beforeDestroy() {
    // 销毁dom大小变化监听
    if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize);
  }
};
</script>
