<template>
  <div class="AdvancedQuery">
    <div class="AdvancedQuery_from">
      <el-scrollbar style="height: 100%" :horizontal="false">
        <el-form ref="paramsForm" class="query-params" :model="paramsForm" :rules="paramsForm.validateRules">
          <el-row class="query-params-wrapper">
            <el-col v-for="(row, rowIndex) in paramsForm.params" class="query-params-wrapper-list flex-wrap" :key="rowIndex" :span="24">
              <el-form-item v-for="(col, colIndex) in paramsTableCols" :key="colIndex" :prop="'params.' + rowIndex + '.' + col.prop" :rules="paramsForm.validateRules[col.prop]">
                <template v-if="
                  col.prop === 'comparisonOperator' ||
                  col.inputType[rowIndex] === 'select'
                ">
                  <el-select style="width: 120px;" v-model="row[col.prop]" placeholder="请选择" @change="
                    value => {
                      selectChangeHandler(value, rowIndex, colIndex)
                    }
                  ">
                    <el-option v-for="(option, i) in col.options[rowIndex]" :key="i" :value="option.value" :label="option.label" />
                  </el-select>
                </template>
                <template v-else-if="col.inputType === 'select'">
                  <el-select style="width: 130px;" v-model="row[col.prop]" placeholder="请选择" @change="
                    value => {
                      selectChangeHandler(value, rowIndex, colIndex)
                    }
                  ">
                    <el-option v-for="(option, i) in col.options" :key="i" :value="option.value" :label="option.label" />
                  </el-select>
                </template>
                <template v-else-if="
                  ['varchar', 'text', 'longtext'].includes(
                    col.inputType[rowIndex]
                  )
                ">
                  <el-input v-model="row[col.prop]" placeholder="请输入" :disabled="
                    col.prop === 'paramValue' && paramsForm.disabled[rowIndex]
                  " />
                </template>
                <template v-else-if="col.inputType[rowIndex] === 'number'">
                  <el-input v-model="row[col.prop]" placeholder="请输入" :disabled="
                    col.prop === 'paramValue' && paramsForm.disabled[rowIndex]
                  " @keydown.native="inputHold(row[col.prop])" @input="inputLimit(row[col.prop], rowIndex)" @blur="inputFix(row[col.prop], rowIndex)" />
                </template>
                <template v-else-if="col.inputType[rowIndex] === 'date'">
                  <el-date-picker v-model="row[col.prop]" type="date" format="yyyy-MM-dd" value-format="yyyy-MM-dd" placeholder="请选择" :clearable="false" />
                </template>
                <template v-else-if="col.inputType[rowIndex] === 'datetime'">
                  <el-date-picker v-model="row[col.prop]" type="datetime" format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择" :clearable="false" />
                </template>
                <template v-else-if="col.inputType === 'delete'">
                  <i class="clickable-delete el-icon-error" @click="deleteParam(rowIndex)" />
                </template>
                <template v-else-if="col.inputType === 'connector'">
                  <div v-if="row.connector" class="clickable-toggle" @click="toggle(rowIndex)">
                    {{ row.connector === 'and' ? '并且' : '或者' }}
                  </div>
                  <div v-else class="clickable-add" @click="addParamsHandler">
                    <span class="el-icon-circle-plus-outline"></span>
                  </div>
                </template>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </el-scrollbar>
    </div>
    <div class="AdvancedQuery_list">
      <el-scrollbar style="height: 100%" :horizontal="false">
        <div v-for="(item,index) in catchOptions" :key="index">
          <div style="cursor: pointer;" class="flex">
            <span @click="queryRecover(item)" class="AdvancedQuery_list_text">{{ item.itemKey }}</span>
            <el-popconfirm @confirm="queryConfirm(item,index)" :title="'确定删除'+item.itemKey+'吗？'">
              <el-button slot="reference" type="text">删除</el-button>
            </el-popconfirm>
          </div>
          <el-divider v-if="catchOptions.length != index+1"></el-divider>
        </div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script>
import { parseTime } from '@/utils/index'
import { mapGetters } from 'vuex'
const comparisonOperatorOptions = [
  {
    label: '小于等于',
    value: '<=',
  },
  {
    label: '大于等于',
    value: '>=',
  },
  {
    label: '小于',
    value: '<',
  },
  {
    label: '大于',
    value: '>',
  },
  {
    label: '等于',
    value: '=',
  },
  {
    label: '不等于',
    value: '!=',
  },
  // {
  //   label: '为空',
  //   value: 'is Null',
  // },
  // {
  //   label: '不为空',
  //   value: 'is not Null',
  // },
  // {
  //   label: '包含',
  //   value: 'like',
  // },
]
export default {
  name: 'AdvancedQueryForm',
  props: {
    selectOptions: {
      type: Array,
      default: () => []
    }
  },
  data () {
    return {
      queryContent: [],
      catchOptions: JSON.parse(localStorage.getItem('catchOptions')) || [],
      catchOptionsAll: [JSON.parse(localStorage.getItem('catchOptions'))] || [],
      flightDate: new Array(2).fill(parseTime(new Date(), '{y}-{m}-{d}')),
      paramsForm: {
        params: [],
        validateRules: {
          paramKey: [
            {
              required: true,
              message: '请选择项',
              trigger: ['change', 'blur'],
            },
          ],
          paramValue: [
            {
              required: true,
              message: '请选择或输入值',
              trigger: ['change', 'blur'],
            },
          ],
        },
        disabled: [],
      },
      checkValue: '',
      paramsTableCols: [
        {
          prop: 'paramKey',
          // label: '项',
          inputType: 'select',
          options: [],
        },
        {
          prop: 'comparisonOperator',
          // label: '比较符',
          inputType: 'select',
          options: new Array(2).fill(
            comparisonOperatorOptions.slice(0, 5).reverse()
          ),
        },
        {
          prop: 'paramValue',
          // label: '值',
          inputType: [],
          options: [],
        },
        {
          prop: 'delete',
          inputType: 'delete',
        },
        {
          prop: 'connector',
          // label: '连接',
          inputType: 'connector',
        },
      ],
      columnSet: {},
    }
  },
  computed: {
    ...mapGetters(['authMsg']),
  },
  watch: {
    'paramsForm.params': {
      handler (params) {
        const { length } = params
        params[length - 1].connector = ''
        if (params[length - 2] && !params[length - 2].connector) {
          params[length - 2].connector = 'and'
        }
      },
    },
  },
  mounted () {
    this.queryHandler()
  },
  methods: {
    queryHandler () {
      const colDatas = this.authMsg
      if (colDatas?.length) {
        const columns = colDatas.filter(item => item.isfiltercolumn)
        const datas = _.orderBy(columns, ['displaynumber'], ['asc', 'desc'])
        this.getColumnSet(datas)
      }
      if (!this.paramsForm.params.length) {
        this.addParamsHandler()
      }
    },
    advancedQueryHandler () {
      try {
        this.$refs['paramsForm'].validate(valid => {
          if (!valid) {
            throw new Error()
          }
        })
        const queryContent = []
        const params = this.paramsForm.params
        const len = params.length
        for (let i = 0; i < len; i++) {
          const prev = params[i - 1]
          const current = params[i]
          const next = params[i + 1]
          const value = ['is Null', 'is not Null'].includes(
            current.comparisonOperator
          )
            ? ''
            : current.paramValue
          const obj = {
            column: current.paramKey,
            comparator: current.comparisonOperator,
            value,
            connector: current.connector,
          }
          if (
            !prev ||
            prev.connector === 'and' ||
            (prev.paramKey && prev.paramKey !== current.paramKey)
          ) {
            obj.left = '('
          } else {
            obj.left = ''
          }
          if (
            !next ||
            current.connector === 'and' ||
            (next.paramKey && next.paramKey !== current.paramKey)
          ) {
            obj.right = ')'
          } else {
            obj.right = ''
          }
          queryContent.push(obj)
        }
        this.queryContent = queryContent
        this.sendColData()
      } catch (error) {
        error.message && this.$message.error(error.message)
      }
    },
    sendColData () {
      this.$emit('getAdvancedQueryData', this.queryContent)
    },
    addParamsHandler () {
      this.paramsTableCols[2].inputType.push('text')
      this.paramsForm.params.push({
        paramKey: '',
        comparisonOperator: '',
        paramValue: '',
        connector: '',
      })
    },
    selectChangeHandler (value, rowIndex, colIndex) {
      if (colIndex === 0) {
        // const datas = this.tableColMunt.filter(item => item.columnName == value)
        const { dataType, options } = this.columnSet[value]
        // const { dataType, options } = datas[0]
        // 下拉框发生改变清空之前的数据
        this.paramsForm.params[rowIndex].paramValue = ''
        if (dataType === 'date') {
          this.paramsTableCols[1].options[rowIndex] = comparisonOperatorOptions
            .slice(0, 5)
            .reverse()
          this.paramsTableCols[2].inputType[rowIndex] = 'date'
        } else if (dataType === 'datetime') {
          this.paramsTableCols[1].options[rowIndex] = comparisonOperatorOptions
            .slice(0, 5)
            .reverse()
          this.paramsTableCols[2].inputType[rowIndex] = 'datetime'
        } else if (options) {
          this.paramsTableCols[1].options[rowIndex] =
            comparisonOperatorOptions.slice(4, 5)
          this.paramsTableCols[2].inputType[rowIndex] = 'select'
          this.paramsTableCols[2].options[rowIndex] = options
          this.paramsForm.params[rowIndex].paramValue = ''
        } else if (dataType === 'number') {
          this.paramsTableCols[1].options[rowIndex] = comparisonOperatorOptions
            .slice(0, 5)
            .reverse()
          this.paramsTableCols[2].inputType[rowIndex] = 'number'
          this.paramsForm.params[rowIndex].paramValue = ''
        } else {
          this.paramsTableCols[1].options[rowIndex] =
            comparisonOperatorOptions.slice(4)
          this.paramsTableCols[2].inputType[rowIndex] = 'text'
        }
        this.paramsForm.params[rowIndex].comparisonOperator =
          this.paramsTableCols[1].options[rowIndex][0].value
      } else if (colIndex === 1) {
        if (['is Null', 'is not Null'].includes(value)) {
          this.paramsForm.params[rowIndex].paramValue = ' '
          this.paramsForm.disabled[rowIndex] = true
        } else {
          this.paramsForm.disabled[rowIndex] = false
        }
      }
    },
    inputHold (value) {
      this.checkValue = value
    },
    inputLimit (value, rowIndex) {
      if (!/^[\-|\+]?((([1-9][0-9]*)|0)(\.[0-9]{0,2})?)?$/.test(value)) {
        this.paramsForm.params[rowIndex].paramValue = this.checkValue
      }
    },
    inputFix (value, rowIndex) {
      if (value?.at(-1) === '.') {
        this.paramsForm.params[rowIndex].paramValue = value.slice(0, -1)
      }
    },
    deleteParam (rowIndex) {
      this.paramsTableCols[2].inputType.splice(rowIndex, 1)
      this.paramsForm.params.splice(rowIndex, 1)
      this.paramsForm.disabled.splice(rowIndex, 1)
    },
    toggle (rowIndex) {
      const { connector } = this.paramsForm.params[rowIndex]
      this.paramsForm.params[rowIndex].connector =
        connector === 'and' ? 'or' : 'and'
    },
    getColumnSet (columnSet) {
      const reflect = {}
      columnSet.forEach(async item => {
        if (!this.columnSet[item.columncode]) {
          this.columnSet[item.columncode] = item

          this.paramsTableCols[0].options.push({
            label: item.columnname,
            value: item.columncode,
          })
        }
      })
    },
    //收藏
    advancedQueryCollect () {
      this.advancedQueryHandler()
      if (!this.queryContent.length) return
      this.$prompt('请输入收藏标题', '收藏', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /^.+$/,
        inputErrorMessage: '请输入收藏标题'
      }).then(({ value }) => {
        this.catchOptionsAll.push(this.queryContent)
        const catchItem = {
          itemId: this.catchOptionsAll.length,
          itemKey: value,
          itemVal: this.catchOptionsAll?.at(-1)
        }
        this.catchOptions.push(catchItem)
        localStorage.setItem('catchOptions', JSON.stringify(this.catchOptions))
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '取消输入'
        });
      });
    },
    //删除收藏
    queryConfirm (item, index) {
      const catchCopy = this.catchOptions
      catchCopy.splice(index, 1)
      this.catchOptionsAll = []
      this.catchOptionsAll = [catchCopy]
      localStorage.setItem('catchOptions', JSON.stringify(catchCopy))
    },
    //收藏查询
    queryRecover (item) {
      const { itemVal } = item
      this.queryRecoverFunc(itemVal)
    },
    //查询恢复
    queryRecoverFunc (itemArray) {
      if (!itemArray.length) return
      const [datas, types] = [[], []]
      itemArray.forEach(item => {
        if (isNaN(item.value) && !isNaN(Date.parse(item.value))) {
          types.push('date')
        } else {
          types.push('text')
        }
        const paramValue = ['is Null', 'is not Null'].includes(
          item.comparisonOperator
        )
          ? ' '
          : item.value
        const obj = {
          // leftBrackets: item.left,
          paramKey: item.column,
          comparisonOperator: item.comparator,
          // rightBrackets: item.right,
          paramValue,
          connector: item.connector,
        }
        datas.push(obj)
      })
      this.queryHandler()
      setTimeout(() => {
        this.paramsTableCols[1].options = new Array(itemArray.length).fill(
          comparisonOperatorOptions.slice(0, 5).reverse()
        )
        this.paramsTableCols[2].inputType = types
        this.paramsForm.params = datas
      }, 200)
    }
  }
}
</script>

<style lang="scss" scoped>
.AdvancedQuery {
  height: calc(100vh - 172px);
  position: relative;
  width: 100%;
  &_from {
    height: 80%;
  }
  &_list {
    height: 20%;
  }
  .query-params-wrapper-list {
    .el-form-item {
      margin-right: 10px;
      &:nth-child(3) {
        margin-right: 0;
      }
      &:last-child {
        margin-right: 0;
      }
    }
  }
  .clickable-delete {
    width: 39px;
    height: 40px;
    text-align: center;
    line-height: 40px;
    font-size: 20px;
    border: 1px solid #dcdfe6;
    border-left: none;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-radius: 2px;
    cursor: pointer;
  }
  .clickable-toggle {
    font-size: 14px;
    font-family: Microsoft YaHei;
    text-decoration: underline;
    color: #409eff;
    cursor: pointer;
  }
  .clickable-add {
    height: 40px;
    text-align: center;
    font-size: 20px;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    .clickable-wrapper {
      width: 20px;
      height: 20px;
      line-height: 28px;
      border-radius: 50%;
      border: 1px solid #409eff;
      color: #409eff;
    }
    &:hover .clickable-wrapper {
      background-color: #409eff;
      color: #fff;
    }
  }
}
</style>