<template>
  <div class="aos-ref">
    <el-select
      v-if="editable"
      ref="aosRef"
      v-model="refValue"
      filterable
      :multiple="multiple"
      :multipleLimit="multipleLimit"
      :collapse-tags="collapseTags"
      :clearable="clearable"
      :disabled="disabled"
      :placeholder="placeholder"
      default-first-option
      :allow-create="allowCreate"
      remote
      :remote-method="handleRemoteMethod"
      :loading="false"
      @change="handleRefChange"
      @visible-change="handleVisibleChange"
      @clear="handleClear"
      @blur="handleBlur"
      @focus="handleFocus"
      @remove-tag="handleRemoveTag">
      <el-option
        v-for="item in options"
        :key="item.code"
        :label="item.value"
        :value="item.code">
      </el-option>
      <template slot="append" v-if="appendIcon">
        <i class="el-icon-plus" @click="handleAppendPlusClick"></i>
      </template>
    </el-select>
    <div v-else class="el-form-item__content aos-form-input-text">
      {{onlyTranslate ? translateRefValueLable : refValueLable}}
    </div>
  </div>
</template>

<script>
export default {
  name: 'AosRef',
  props: {
    // 参照对应的编码
    refCode: {
      type: String,
      required: true
    },
    value: {
      type: [String, Array],
      required: true
    },
    // 编辑状态
    editable: {
      type: Boolean,
      required: true,
      default: true
    },
    // 防抖
    debounce: {
      type: Number,
      default: 300
    },
    // 参照下拉列表的位置
    placement: {
      type: String,
      default: 'bottom-start'
    },
    // 提示
    placeholder: {
      type: String,
      default: '请选择'
    },
    // 是否可清空
    clearable: {
      type: Boolean,
      default: true
    },
    // 禁用状态
    disabled: {
      type: Boolean,
      default: false
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 是否折叠多选
    collapseTags: {
      type: Boolean,
      default: false
    },
    // 多选限制
    multipleLimit: {
      type: Number,
      default: 0
    },
    // 查询参数
    queryParams: {
      type: Object,
      default: function() {
        return {};
      }
    },
    // 过滤参数
    filters: {
      type: Array,
      default: function () {
        return []
      }
    },
    // 默认选中第一项
    firstDefault: {
      type: Boolean,
      default: false
    },
    // 参照显示的类型,默认是输入框,暂时未启用
    showType: {
      type: String,
      default: 'input',
      validator: function (value) {
        return ['input', 'table'].indexOf(value) !== -1
      }
    },
    // 只翻译，适用于只显示非编辑状态
    onlyTranslate: {
      type: Boolean,
      default: false
    },
    // 只翻译时外部传回来的值,需要和onlyTranslate配合使用
    translateRefValueLable: {
      type: String,
      default: ''
    },
    // 是否允许通过输入框创建新的条目
    allowCreate : {
      type: Boolean,
      default: false
    },
    // 是否显示尾部的添加
    appendIcon: {
      type: Boolean,
      default: false
    },
    customerUrl: {
      type: String
    }
  },
  watch: {
    refValue: function (val, oldVal) {
      if (!this.onlyTranslate && this.options && this.options.length > 0 && val && !this.$_.isEqual(val, oldVal)) {
        Promise.all([this.handleRemoteMethod()]).then(() =>{
          this.setRefValue(val)
        })
      }
    },
    filters:{
      handler: function (val, oldVal) {
        if (!this.onlyTranslate && val && Object.keys(val).length > 0) {
          Promise.all([this.handleRemoteMethod()]).then(() =>{
            this.setRefValue(val)
          })
        }
      },
      deep: true
    },
    value: function (val, oldVal) {
      if (!this.onlyTranslate && !this.$_.isEqual(val, oldVal)) {
        this.init()
      }
    },
    refCode: function (val, oldVal) {
      if (!this.onlyTranslate && !this.$_.isEqual(val, oldVal)) {
        this.init()
      }
    },
    customerUrl: function (val, oldVal) {
      if (!this.onlyTranslate && !this.$_.isEqual(val, oldVal)) {
        this.init()
      }
    }
  },
  created () {
    if (!this.onlyTranslate) {
      this.init()
      this.firstInit = true
    }
  },
  data() {
    return {
      options: [],
      refValue: '',
      refValueLable: '',
      firstInit: true
    };
  },
  methods: {
    handleAppendPlusClick () {
      this.$emit('plus-click')
    },
    /**
     * @description: 参照远程搜索
     * @param {type} 输入框的值
     * @return:
     */
    handleRemoteMethod(queryString) {
      if (!this.refCode) {
        this.$message({
          type: 'error',
          message: this.refCode + '对应的 refCode 不能为空.'
        });
        return;
      }
      let submitData;
      const filters = Object.prototype.toString.call(this.filters) === '[object Array]' ? this.filters : []
      const content = queryString ? queryString : ''
      if (this.showType === 'dialog') {
        submitData = {
          content: content,
          page: this.page,
          size: this.size,
          filters: filters
        };
      } else {
        submitData = {
          content: content,
          filters: filters
        };
      }
      // let queryParamsKeys = Object.keys(this.queryParams);
      // if (queryParamsKeys.length > 0) {
      //   queryParamsKeys.forEach((item) => {
      //     params[item] = this.queryParams[item];
      //   });
      // }
      let url = '/core/api/ref/simple-search/'+ this.refCode
      if (this.customerUrl) {
        url = this.customerUrl + this.refCode
      }
      return this.$optimizeHttp({
        method: 'post',
        url: '/ap/ref/simple-search/'+ this.refCode,
        data: submitData
      }).then((res) => {
        if (res.status === 200) {
          this.options = JSON.parse(res.data.data);
          if (this.firstInit && this.firstDefault) {
            this.setFirstDefault();
          }
          this.firstInit = false;
        } else {
          this.$message({
            type: 'error',
            message: '请求参照数据失败'
          });
        }
      });
    },

    /**
     * @description: 设置默认第一项,当有值的时候不设置
     * @param {type} none
     * @return: undefined
     */
    setFirstDefault() {
      if (this.multiple) {
        if (this.refValue.length <= 0) {
          this.refValue = [];
          this.refValue.push(this.options[0].code);
          this.$emit('change', this.refValue);
        }
      } else {
        if (!this.refValue) {
          if (Array.isArray(this.options) && this.options[0]) {
            this.refValue = this.options[0].code;
            this.$emit('change', this.refValue);
          }
        }
      }
    },
    handleRefChange(data) {
      this.setRefValue(data);
      let emitData = '';
      if (this.multiple) {
        if (data && data.length > 0) {
          data.forEach(item => {
            emitData += ',';
            emitData += item;
          });
        }
      } else {
        emitData = data;
      }
      this.$emit('change', emitData);
    },
    handleVisibleChange(data) {
      this.$emit('visible-change', data);
    },
    handleRemoveTag(tag) {
      this.$emit('remove-tag', tag);
    },
    handleClear() {
      this.$emit('clear');
    },
    handleBlur(e) {
      this.$emit('blur', e);
    },
    handleFocus(e) {
      this.handleRemoteMethod()
      this.$emit('focus', e);
    },
    setRefValue(data) {
      let copyData = void 0
      if (this.multiple && data) {
        if (typeof data === 'string') {
          copyData = data.split(',').filter(item => item)
        } else {
          copyData = this.$_.cloneDeep(data)
        }
        this.refValueLable = '';
        if (copyData.length > 0) {
          copyData.forEach((item, index) => {
            const sourceData = this.$_.find(this.options, { code: item });
            if (sourceData) {
              this.refValueLable += sourceData.value;
              if (index < copyData.length - 1) {
                this.refValueLable += ',';
              }
            }
          });
        }
      } else {
        const sourceData = this.$_.find(this.options, { code: data });
        if (sourceData) {
          this.refValueLable = sourceData.value;
        } else {
          this.refValueLable = '';
        }
      }
    },
    init() {
      if (this.multiple) {
        if (this.value) {
          this.value += ''
          const value = this.value.split(',')
          this.refValue = value.filter(item => item)
        } else {
          this.refValue = [];
        }
      } else {
        this.refValue = this.value || '';
      }
      Promise.all([this.handleRemoteMethod()]).then(() =>{
        this.setRefValue(this.value);
      });
    }
  }
};
</script>
