<template>
  <div class="advance">
    <!--高级查询-->
    <div class="advance-wrapper">
      <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"
            :key="rowIndex"
            :span="12"
          >
            <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
                  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
                  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"
                >
                  <div class="clickable-wrapper">
                    <i class="el-icon-plus" />
                  </div>
                </div>
              </template>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
  </div>
</template>

<script>
import { parseTime } from '@/utils/index'
import { mapGetters } from 'vuex'
import { formatOrder } from '@/utils/validate'
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: 'AdvancedNew',
  props: {
    tableColMunt: {
      type: Array,
      default: () => [],
    },
    dataQuery: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      queryContent: [],
      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: {
    dataQuery: {
      handler(arr) {
        if (arr && arr.length) {
          const datas = []
          const types = []
          arr.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(arr.length).fill(
              comparisonOperatorOptions.slice(0, 5).reverse()
            )
            this.paramsTableCols[2].inputType = types
            this.paramsForm.params = datas
          }, 200)
        } else {
          this.paramsForm.params = []
        }
      },
      deep: true,
      immediate: true,
    },
    '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 && colDatas.length) {
        const columns = colDatas.filter(item => String(item.is_search) === '1')
        const datas = formatOrder(columns)
        this.getColumnSet(datas)
      }
      if (!this.paramsForm.params.length) {
        this.addParamsHandler()
      }
    },
    sendColData() {
      this.$emit('getColData', 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]
        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)
      }
    },
    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)
      }
    },
    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'
    },
    async getColumnSet(columnSet) {
      const reflect = {}
      columnSet.forEach(async column => {
        if (!this.columnSet[column.columnName]) {
          this.columnSet[column.columnName] = column
          if (
            (column.listqueryTemplateID ?? '') !== '' &&
            !this.columnSet[column.columnName].options
          ) {
            if (reflect[column.listqueryTemplateID]) {
              reflect[column.listqueryTemplateID].push(column.columnName)
            } else {
              reflect[column.listqueryTemplateID] = [column.columnName]
            }
          }
          this.paramsTableCols[0].options.push({
            label: column.columnLabel,
            value: column.columnName,
          })
        }
      })
    },
  },
}
</script>

<style lang="scss" scoped>
.advance-wrapper {
  padding: 0 24px 20px;
  background: #f0f3f7;
  ::v-deep .query-params {
    padding: 0;
    &-wrapper {
      padding-top: 15px;
      height: 200px;
      overflow-x: hidden;
      overflow-y: auto;
      > .el-col {
        margin-top: 15px;
        display: flex;
        &:nth-child(1),
        &:nth-child(2) {
          margin-top: 0;
        }
      }
    }
    .el-form-item {
      margin: 0;
      height: 50px;
      margin-bottom: 0;
      background-color: #fff;
      border: 1px solid #409eff;
      border-right: none;
      &:first-child {
        border-radius: 4px 0px 0px 4px;
      }
      &:nth-last-child(2) {
        border-radius: 0px 4px 4px 0px;
        border-right: 1px solid#409EFF;
      }
      &:nth-child(3) {
        flex: 1;
        .el-input:not(.el-date-editor) .el-input__inner {
          text-align: center;
        }
        .el-form-item__error {
          left: 50%;
          transform: translateX(-50%);
        }
      }
      &:last-child {
        width: 76px;
        text-align: center;
        background-color: transparent;
        border: none;
      }
      &__content {
        line-height: 48px;
      }
      .el-form-item__error {
        top: 60%;
        left: 14px;
      }
      .el-input__inner {
        height: 48px;
        border: none;

        background: transparent;
        color: #101116;
        font-family: Helvetica, 'Microsoft YaHei';
      }
      &.is-error .el-input__inner::-webkit-input-placeholder {
        visibility: hidden;
      }

      .el-select {
        .el-icon-arrow-up::before {
          content: '\e78f';
          color: #101116;
        }
        .el-icon-arrow-down::before {
          content: '\e790';
          color: #101116;
        }
      }
    }
    .clickable-delete {
      width: 48px;
      height: 48px;
      text-align: center;
      line-height: 48px;
      font-size: 20px;
      cursor: pointer;
    }
    .clickable-toggle {
      font-size: 14px;
      font-family: Microsoft YaHei;
      text-decoration: underline;
      color: #409eff;
      cursor: pointer;
    }
    .clickable-add {
      height: 48px;
      text-align: center;
      font-size: 20px;
      cursor: pointer;
      display: flex;
      justify-content: center;
      align-items: center;
      .clickable-wrapper {
        width: 30px;
        height: 30px;
        line-height: 28px;
        border-radius: 50%;
        border: 1px solid #409eff;
        color: #409eff;
      }
      &:hover .clickable-wrapper {
        background-color: #409eff;
        color: #fff;
      }
    }
  }
}
</style>
