<!--
 * @Description: 
 * @Autor: Heloise
 * @Date: 2022-07-15 16:56:43
 * @LastEditors: Heloise
 * @LastEditTime: 2022-08-12 09:36:27
-->
<template>
  <div class="el-basal-filter">
    <div class="el-basal-filter__relation">
      <div :class="[`${relation}-line`]"></div>
      <el-button :type="relation" @click="onAndOrChange">{{
        relation === "and" ? "且" : "或"
      }}</el-button>
    </div>
    <el-form class="el-basal-filter__form" ref="ruleForm" :model="ruleForm">
      <div
        class="el-basal-filter__form-item"
        v-for="(itemVal, index) in ruleForm.values"
        :key="itemVal.id"
        @mouseenter="hoverIndex = index"
        @mouseleave="hoverIndex = -1"
      >
        <!-- 单选下拉、远程搜索下拉、级联选择 -->
        <el-single-form-item
          v-if="['select', 'remoteSelect', 'cascader'].includes(basalType)"
          class="el-basal-filter__key"
          :formType="basalType"
          :propKey="'values.' + index + '.key'"
          :bindValue="itemVal.key"
          @getFormVal="getFormVal"
          :options="conditions"
          :placeholder="'请选择' + btnTxt"
          :props="{
            children: 'condition',
            value: 'key',
            label: 'value',
          }"
          :remote-method="
            (query) => {
              remoteFirMethod(query, index);
            }
          "
          :filterable="['select'].includes(ruleFormConfig[index].input)"
          v-bind="$attrs"
          @change="firstChange($event, index)"
        >
          <slot name="first-select" :options="conditions">
            <el-option
              v-for="item in conditions"
              :key="item.key"
              :value="item.key"
              :label="item.value"
            >
            </el-option>
          </slot>
        </el-single-form-item>
        <el-single-form-item
          v-if="typeShow(itemVal)"
          class="el-basal-filter__type"
          formType="select"
          :propKey="'values.' + index + '.opType'"
          :bindValue="itemVal.opType"
          @getFormVal="getFormVal"
          @change="opTypeChange($event, index)"
        >
          <el-option
            v-for="item in ruleFormConfig[index].tagList"
            :key="item.key"
            :value="item.key"
            :label="item.value"
          >
          </el-option>
        </el-single-form-item>
        <el-single-form-item
          v-if="lastShow(itemVal)"
          :class="[
            'el-basal-filter__value',
            `el-basal-filter__${ruleFormConfig[index].input}`,
          ]"
          :formType="ruleFormConfig[index].input"
          :propKey="'values.' + index + '.value'"
          :bindValue="itemVal.value"
          @getFormVal="getFormVal"
          :options="ruleFormConfig[index].config"
          placeholder="请选择"
          :multiple="
            ['multRemoteSelect', 'multSelect'].includes(
              ruleFormConfig[index].input
            )
          "
          :filterable="
            ['select', 'multSelect'].includes(ruleFormConfig[index].input)
          "
          :remote-method="
            (query) => {
              remoteLasMethod(query, itemVal, index);
            }
          "
          v-bind="$attrs"
        >
          <slot name="last-select" :options="ruleFormConfig[index].config">
            <el-option
              v-for="item in ruleFormConfig[index].config"
              :key="item.key"
              :value="item.key"
              :label="item.value"
            >
            </el-option>
          </slot>
        </el-single-form-item>
        <el-button
          v-if="
            (hoverIndex === index || showAllDel) && (showFirstDel || ruleFormConfig.length > 1)
          "
          class="el-basal-filter__form-btn"
          @click="removeItem(index)"
          type="shadow"
          size="mini"
          icon="bi-iconfont-delete
"
        ></el-button>
      </div>
      <el-form-item v-if="showAdd" class="el-form-item-btn">
        <el-button
          @click="addItemCheck()"
          type="solid"
          size="small"
          icon="bi-iconfont-add"
          >{{ btnTxt }}</el-button
        >
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
const uuid = require('uuid');
export default {
  name: 'ElBasalFilter',
  props: {
    btnTxt: { type: String, default: '属性' },
    basalType: { type: String, default: 'select' },
    showAdd: { type: Boolean, default: true },
    showAllDel: { type: Boolean, default: false },
    showFirstDel: { type: Boolean, default: false },
    resultArr: { default: () => [] }, // 回显的数据
    conditions: {
      type: Array,
      default: () => []
    } // 配置
  },
  data() {
    return {
      hoverIndex: -1,
      relation: 'and',
      ruleForm: {
        values: []
      },
      ruleFormConfig: []
    };
  },
  created() {
    this.relation =
      this.resultArr && this.resultArr.length
        ? this.resultArr[0].relation
        : 'and';
    this.resultArr.forEach(() => {
      this.addItem();
    });
    this.$nextTick(() => {
      this.ruleForm.values = this.resultArr;
      this.ruleForm.values.forEach((item, index) => {
        item['id'] = uuid.v1();
        this.dealRowData('init', item.key, index);
      });
    });
  },
  watch: {
    resultArr: {
      handler: function(newVal) {
        if (newVal && newVal.length) {
          this.ruleForm.values = newVal;
          this.ruleForm.values.forEach((item, index) => {
            item['id'] = uuid.v1();
            this.dealRowData('init', item.key, index);
          });
        }
      },
      deep: true,
      immediate: false
    }
  },
  methods: {
    typeShow(itemVal) {
      return (
        (itemVal.key && this.basalType !== 'cascader') ||
        (this.basalType === 'cascader' &&
          itemVal.key.constructor === Array &&
          itemVal.key.length > 0)
      );
    },
    lastShow(itemVal) {
      return (
        this.typeShow(itemVal) &&
        itemVal.opType &&
        ![12, 13, 19, 20].includes(itemVal.opType)
      );
    },
    /**
     * @description: 处理表单每一行的数据
     * @param {*} str--为init时为初始化，为change时为第一个下拉值改变时处理
     * @param {*} e
     * @param {*} index
     * @return {*}
     */
    dealRowData(str, e, index) {
      let tempArr = [];
      tempArr = this.conditions;
      let obj = null;
      if (this.basalType === 'cascader') {
        if (e.constructor === Array && e.length > 0) {
          tempArr = this.conditions.find((item) => item.key === e[0]).condition;
          obj = tempArr.find((item) => item.key === e[1]);
        } else {
          return;
        }
      } else {
        tempArr = this.conditions;
        obj = tempArr.find((item) => item.key === e);
      }
      if (!obj) {
        return;
      }
      this.ruleFormConfig[index] = {
        config: obj.config,
        tagList: obj.opType,
        input: obj.input,
        type: obj.type
      };
      if (str === 'change') {
        this.ruleForm.values[index].opType = '';
        this.initValue(obj, index);
      } else {
        this.dealOpType(index, obj.opType);
      }
    },
    initValue(obj, index) {
      if (
        ['multSelect', 'multRemoteSelect', 'cascader', 'dateRange'].includes(
          obj.input
        )
      ) {
        this.ruleForm.values[index].value = [];
      } else {
        this.ruleForm.values[index].value = '';
      }
    },
    /**
     * @description: 第一个下拉框（选择字段）
     * @param {*} e
     * @param {*} index
     * @return {*}
     */
    firstChange(e, index) {
      this.$refs.ruleForm.fields.forEach((item) => {
        if (
          item.prop === `values.${index}.opType` ||
          item.prop === `values.${index}.value`
        ) {
          item.resetField();
        }
      });
      this.dealRowData('change', e, index);
      this.ruleForm.values[index].opType = '';
    },
    /**
     * @description: 第二个下拉框（选择条件）
     * @param {*} e
     * @param {*} index
     * @return {*}
     */
    opTypeChange(e, index) {
      // 针对选择条件下拉之后改变input
      this.$refs.ruleForm.fields.forEach((item) => {
        if (item.prop === `values.${index}.value`) {
          item.resetField();
        }
      });
      this.$nextTick(()=>{
        this.$refs.ruleForm.fields.forEach((item) => {
          if (item.prop === `values.${index}.value`) {
            item.resetField();
          }
        });
      });
      this.dealOpType(index, e);
      this.initValue(this.ruleFormConfig[index], index);
    },
    dealOpType(index, opType) {
      if (
        this.ruleFormConfig[index].input === 'inputNumber' ||
        this.ruleFormConfig[index].input === 'number'
      ) {
        // 当计算逻辑为等于（数组）、不等于时（数组），后接文本框，支持输入数组，即多个数字，以中/英文逗号隔开，不受小数位限制，仅做数字校验
        if ([10, 15].includes(opType)) {
          this.ruleFormConfig[index].input = 'inputNumberArr';
        }
      } else if (this.ruleFormConfig[index].input === 'date') {
        // 当计算逻辑为等于时，后面接日期范围选择器
        if ([1].includes(opType)) {
          this.ruleFormConfig[index].input = 'dateRange';
        }
      }
    },
    getFormVal(val, propKey) {
      let arr = propKey.split('.');
      this.ruleForm.values[arr[1]][arr[2]] = val;
    },
    onAndOrChange() {
      this.relation = this.relation === 'and' ? 'or' : 'and';
    },
    /**
     * @description: 第一个框为远程搜索
     * @param {*} query--输入内容
     * @param {*} index--当前行 index
     * @return {*}
     */
    remoteFirMethod(query, index) {
      // console.log(query, index);
      this.$emit('remoteFirMethod', query, index);
    },
    /**
     * @description: 第三个框为远程搜索
     * @param {*} query--输入内容
     * @param {*} index--当前行 index
     * @return {*}
     */
    remoteLasMethod(query, itemVal, index) {
      // console.log(query, index);
      this.$emit('remoteLasMethod', query, itemVal, index);
    },
    addItemCheck() {
      if (this.submitForm()) {
        this.addItem();
      }
    },
    addItem() {
      this.ruleForm.values.push({
        id: uuid.v1(),
        key: this.basalType === 'cascader' ? [] : '',
        opType: null,
        value: ''
      });
      this.ruleFormConfig.push({
        config: [],
        tagList: [],
        input: '',
        type: ''
      });
    },
    removeItem(index) {
      this.ruleForm.values.splice(index, 1);
      this.ruleFormConfig.splice(index, 1);
    },
    /**
     * @description: 校验
     * @return {*}
     */
    submitForm() {
      let flag = false;
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          flag = true;
          return true;
        } else {
          flag = false;
          return false;
        }
      });
      return flag;
    },
    /**
     * @description: 返回表单值
     * @return {*}
     */
    getBasalFilterVal() {
      let newVal = this.ruleForm.values;
      if (newVal && newVal.length) {
        newVal.forEach((item, index) => {
          item.type = this.ruleFormConfig[index].type;
          item.relation = this.relation;
          delete item.id;
        });
        return newVal;
      } else {
        return [];
      }
    },
    resetForm() {
      this.$refs.ruleForm.resetFields();
      this.ruleForm.values.length = 0;
      this.ruleFormConfig.length = 0;
      this.addItem();
    }
  }
};
</script>
