<template>
  <div class="aos-ref">
    <el-select
      v-if="editable && showType === 'select'"
      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-if="!editable" class="el-form-item__content aos-form-input-text">
      {{onlyTranslate ? translateRefValueLable : refValueLable}}
    </div>
    <div v-if="editable && showType === 'checkbox' && multiple" class="aos-defdoc__container">
      <!-- <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox> -->
      <el-checkbox-group v-model="refValue" @change="handleCheckedChange">
        <el-checkbox v-for="item in options" :label="item.code" :key="item.code">{{item.value}}</el-checkbox>
      </el-checkbox-group>
    </div>
    <div v-if="editable && showType === 'button' && multiple" class="aos-defdoc__container">
      <el-checkbox-group v-model="refValue" @change="handleCheckedChange" size="mini">
        <el-checkbox-button v-for="item in options" :label="item.code" :key="item.code">{{item.value}}</el-checkbox-button>
      </el-checkbox-group>
    </div>
    <div v-if="editable && showType === 'checkbox' && !multiple" class="aos-defdoc__container">
       <el-radio-group v-model="refValue" @change="handleRadioChange">
        <el-radio v-for="item in options"  :label="item.code" :key="item.code">{{item.value}}</el-radio>
      </el-radio-group>
    </div>
    <div v-if="editable && showType === 'button' && !multiple" class="aos-defdoc__container">
       <el-radio-group v-model="refValue" @change="handleRadioChange" size="mini">
        <el-radio-button v-for="item in options"  :label="item.code" :key="item.code">{{item.value}}</el-radio-button>
      </el-radio-group>
    </div>
  </div>
</template>

<script>
import debounce from 'throttle-debounce/debounce';
import cloneDeep from 'lodash/cloneDeep';
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: 'select',
      validator: function (value) {
        return ['select', 'table', 'button', 'checkbox'].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
    },
    noRefCode: {
      type: Boolean,
      default: false
    },
    ormCode: {
      type: String
    },
    ormName: {
      type: String
    },
    ormData: {
      type: String
    },
    ormStatus: {
      type: String
    },
    // 是否不使用请求缓存
    immediate: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    emitData () {
      let emitData = '';
      if (this.multiple) {
        if (this.refValue && this.refValue.length > 0) {
          this.refValue.forEach((item,index) => {
            emitData += item;
            if (index < this.refValue.length - 1) {
              emitData += ',';
            }
          });
        }
      } else {
        emitData = this.refValue;
      }
      return emitData
    },
    emitFullData () {
      let emitFullData = [];
      let options = this.options
      if (this.multiple) {
        if (this.refValue && this.refValue.length > 0) {
          this.refValue.forEach(item => {
            const data = this.$_.find(options, { code: item });
            if (data) {
              emitFullData.push(data)
            }
          });
        }
      } else {
        const data = this.$_.find(options, { code: this.refValue });
        if (data) {
          emitFullData.push(data)
        }
      }
      return emitFullData
    }
  },
  watch: {
    // refValue: function (val, oldVal) {
    //   if (!this.onlyTranslate && this.options && this.options.length > 0 && val && !this.$_.isEqual(val, oldVal)) {
    //     this.init()
    //   }
    // },
    filters:{
      handler: function (val, oldVal) {
        if (!this.onlyTranslate && val && Object.keys(val).length > 0) {
          this.init()
        }
      },
      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 () {
    this.debounceHandleEmitChange = debounce(10, this.handleEmitChange)
    if (!this.onlyTranslate) {
      this.init()
      this.firstInit = true
    }
  },
  data() {
    return {
      options: [],
      refValue: '',
      refValueLable: '',
      firstInit: true,
      debounceHandleEmitChange: '',
    };
  },
  methods: {
     getLableByCode () {
      let paramsData = ''
      if (this.multiple) {
        paramsData = this.refValue.join(',')
      } else {
        paramsData = this.refValue
      }
      this.$optimizeHttp({
        url: '/core/api/ref/translate/' + this.refCode,
        method: 'get',
        params: {
          code: paramsData
        }
      }).then((res) => {
        const resData = cloneDeep(res.data)
        this.refValueLable = '';
        if (this.refValue.length > 0) {
          if (this.multiple) {
            this.refValue.forEach((item, index) => {
              const sourceData = this.$_.find(resData, { code: item });
              if (sourceData) {
                this.refValueLable += sourceData.value;
                if (index < this.refValue.length - 1) {
                  this.refValueLable += ',';
                }
              }
            });
          } else {
            const sourceData = this.$_.find(resData, { code: this.refValue });
            if (sourceData) {
              this.refValueLable = sourceData.value;
            } else {
              this.refValueLable = '';
            }
          }
        }
      })
    },
    handleCheckedChange (data) {
      this.refValue = data
      this.setRefValue(data)
      this.handleEmitChange()
    },
    handleRadioChange (data) {
      this.refValue = data
      this.setRefValue(data)
      this.handleEmitChange()
    },
    handleEmitChange () {
      this.$emit('change', this.emitData, this.emitFullData)
    },
    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
        if (this.noRefCode) {
          url = this.customerUrl
        }
      }
      let http = this.$optimizeHttp
      if (this.immediate) {
        http = this.$http
      }
      return http({
        method: 'post',
        url: url,
        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.debounceHandleEmitChange()
        }
      } else {
        if (!this.refValue) {
          if (Array.isArray(this.options) && this.options[0]) {
            this.refValue = this.options[0].code;
            this.debounceHandleEmitChange()
          }
        }
      }
    },
    handleRefChange(data) {
      this.refValue = data
      this.setRefValue(data);
      this.debounceHandleEmitChange()
    },
    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
      let findLabel = true
      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 {
              findLabel = false
            }
          });
        }
      } else {
        const sourceData = this.$_.find(this.options, { code: data });
        if (sourceData) {
          this.refValueLable = sourceData.value;
        } else {
          this.refValueLable = '';
          findLabel = false
        }
      }
      if (!this.onlyTranslate && data && !findLabel) {
        this.getLableByCode()
      }
      this.debounceHandleEmitChange()
    },
    init() {
      if (this.multiple) {
        let value = this.value
        if (value) {
          value += ''
          const valueList = value.split(',')
          this.refValue = valueList.filter(item => item)
        } else {
          this.refValue = [];
        }
      } else {
        this.refValue = this.value || '';
      }
      Promise.all([this.handleRemoteMethod()]).then(() =>{
        this.setRefValue(this.value);
      });
    },
    reset () {
      this.refValue = ''
      this.refValueLable = ''
    }
  }
};
</script>
