<template>
  <el-form
    v-form
    :data-vv-scope="searchFormScope"
    label-position="right"
    @submit.native.prevent
  >
    <div
      class="search-panel__container"
      :class="{ 'mobile-search__container': isMobile }"
    >
      <component
        :is="isFlexLayout ? 'div' : 'el-row'"
        class="search-panel__row"
        :class="{ 'search-field__row': isFlexLayout }"
      >
        <slot></slot>
        <div
          v-if="fieldArray.length && !isMobile"
          :class="{ 'flex-search__group': isFlexLayout }"
          class="search-btn__wrap"
        >
          <el-button
            type="text"
            icon="el-icon-search"
            class="search-btn__wrap_search"
            @click="search(true)"
          >
            {{ isSearchText ? '搜索' : '' }}
          </el-button>
          <el-button
            v-if="hasOftenUsed"
            type="text"
            icon="icon-baocun1"
            @click="save()"
          >
            {{ isSearchText ? '保存' : '' }}
          </el-button>
          <el-button type="text" icon="el-icon-refresh-right" @click="reset">
            {{ isSearchText ? '重置' : '' }}
          </el-button>
        </div>
      </component>
    </div>
    <footer v-if="fieldArray.length && isMobile" class="filter-action__footer">
      <van-button
        type="default"
        class="filter-action__footer--btn"
        @click="reset"
      >
        重置
      </van-button>
      <van-button
        type="info"
        class="filter-action__footer--btn"
        @click="search(true)"
      >
        完成
      </van-button>
    </footer>
    <saveOftenSearch
      ref="saveOftenSearch"
      :field-array="fieldArray"
      :only-often-used-key="onlyOftenUsedKey"
    ></saveOftenSearch>
  </el-form>
</template>
<script>
  import emitter from '@/mixins/emitter.js'
  import utils from '@/utils.js'
  import _ from 'lodash'
  import mobileMode from '@/mixins/mobileMode.js'
  import saveOftenSearch from './saveOftenSearch'
  export default {
    name: 'HtTableSearchPanel',
    componentName: 'HtTableSearchPanel',
    components: { saveOftenSearch },
    mixins: [emitter, mobileMode],
    props: {
      value: Object,
      divide: {
        type: Number,
        default: 4,
        validator: (value) => {
          return value > 0 && value < 5
        },
      },
      labelWidth: {
        type: Number,
        default: 105,
      },
      isFlexLayout: {
        type: Boolean,
        default: false,
      },
      isEnterSearch: {
        //是否使用回车搜索
        type: Boolean,
        default: false,
      },
      isSearchText: {
        type: Boolean,
        default: true,
      },
      displayStyle: String,
    },
    data() {
      return {
        fieldVms: [],
        fieldArray: [],
        formModelExpression: null,
        data: {},
        defaultData: {},
        //选择器,对话框的key-value映射关系，统一从model中赋值到selectorConfig
        selectorConfig: {},
        hasOftenUsed: false, //是否常用按钮
        onlyOftenUsedKey: '', //常用按钮唯一key
      }
    },
    computed: {
      calcSpan: {
        get() {
          return 24 / this.divide
        },
      },
      searchFormScope() {
        return `Form${utils.guid()}`
      },
    },
    created() {
      if (this.$vnode.data.model && this.$vnode.data.model.expression) {
        this.formModelExpression = this.$vnode.data.model.expression
      }
      this.$slots.default &&
        this.$slots.default.forEach((v) => {
          if (!v.componentOptions) {
            return
          }
          this.fieldArray.push({ ...v.componentOptions.propsData })
        })
      this.$on('field-loaded', (ref) => {
        // 搜索条件挂载完成后，添加其实例到数组中
        this.fieldVms.push(ref)
      })
      this.$on('input-change', (obj, prop) => {
        this.fieldArray = this.fieldArray.map((field) => {
          return field.prop == prop ? { ...field, ...obj } : field
        })
      })
      this.$on('search', (isSearchBtn) => this.search(isSearchBtn))

      this.$on('change-TableSearchPanel-fieldArray', (list, id) =>
        this.changeFieldArray(list, id)
      )

      this.isEnterSearch &&
        window.addEventListener('keydown', this.handleSearchEnter)
    },
    mounted() {
      if (this.formModelExpression) {
        this.$set(this.data, this.formModelExpression, this.value)
        this.defaultData = _.cloneDeep(this.value)
      }
      this.broadcast('HtTableSearchField', 'panel-props', [
        this.labelWidth,
        this.calcSpan,
        this.isFlexLayout,
        this.displayStyle,
      ])
      //常用按钮
      this.hasOftenUsed = this.$parent.$parent.hasOftenUsed || false
      this.onlyOftenUsedKey = this.$parent.$parent.onlyOftenUsedKey || ''
    },
    beforeDestroy() {
      this.isEnterSearch &&
        window.removeEventListener('keydown', this.handleSearchEnter)
    },
    methods: {
      /**
       * 回车搜索
       */
      handleSearchEnter(e) {
        var keyCode = window.event ? e.keyCode : e.which
        if (keyCode == 13) {
          this.search(true)
        }
      },
      changeFieldArray(list, id) {
        let that = this

        if (this.fieldArray.length > 0 && list.length > 0) {
          try {
            list.forEach((item) => {
              let prop = this.fieldArray.find((itemField) => {
                return itemField.prop === item.prop
              })
              if (
                (item.value !== undefined ||
                  item.value !== '' ||
                  item.value !== null) &&
                !prop
              ) {
                throw {
                  type: 'noProp',
                }
              }
            })
          } catch (e) {
            if (e.type === 'noProp') {
              this.$message.warning('查询条件配置项已变更，无法进行有效筛选')
              return
            }
          }

          let idList = []
          if (sessionStorage.getItem('tableSearchItemId')) {
            idList = JSON.parse(sessionStorage.getItem('tableSearchItemId'))
          }
          idList.forEach((itemList) => {
            if (itemList.tableKey == this.onlyOftenUsedKey) {
              idList.splice(idList.indexOf(itemList), 1)
            }
          })
          idList.push({
            tableKey: this.onlyOftenUsedKey,
            id: id,
          })

          sessionStorage.setItem('tableSearchItemId', JSON.stringify(idList))
          this.fieldArray.forEach((item) => {
            item.value = ''
          })
          //恢復默認值
          if (this.formModelExpression) {
            Object.keys(this.data[this.formModelExpression]).forEach((key) => {
              this.$set(
                this.data[this.formModelExpression],
                key,
                this.defaultData[key] ? this.defaultData[key] : ''
              )
            })
          }
          list.forEach((item) => {
            that.fieldArray.forEach((fieldItem) => {
              if (item.prop === fieldItem.prop && item.value) {
                this.$set(fieldItem, 'value', item.value)
                this.broadcast(
                  'HtTableSearchField',
                  'change-TableSearchField-data',
                  [item]
                )
                if (this.formModelExpression) {
                  this.$set(
                    this.data[this.formModelExpression],
                    item.prop,
                    item.value
                  )
                }
              }
            })
          })
          this.search(true, true)
        }
      },
      removeOfetnSearch(isOftenUsed) {
        if (sessionStorage.getItem('tableSearchItemId') && !isOftenUsed) {
          let idList = JSON.parse(sessionStorage.getItem('tableSearchItemId'))

          idList.forEach((item, index) => {
            if (item.tableKey === this.onlyOftenUsedKey) {
              idList.splice(index, 1)
            }
          })
          sessionStorage.setItem('tableSearchItemId', JSON.stringify(idList))
        }
      },
      //isOftenUsed 是否常用按钮點擊
      search(isSearchBtn, isOftenUsed) {
        //清空常用
        this.removeOfetnSearch(isOftenUsed)
        let fields = []
        this.fieldArray.forEach((item) => {
          let selectorCof = item['config']
          if (selectorCof && selectorCof != '') {
            let fieldConfig = JSON.parse(selectorCof)
            let type = fieldConfig['type']
            let typeArray = [
              'text',
              'daterange',
              'select',
              'radio',
              'checkbox',
              'dictionary',
              'date',
            ]
            if (!typeArray.includes(type)) {
              if (fieldConfig && fieldConfig.parameter) {
                for (let key in fieldConfig.parameter) {
                  //从映射关系中取值
                  if (
                    this.selectorConfig &&
                    this.selectorConfig[fieldConfig.parameter[key]]
                  ) {
                    let copy = JSON.parse(JSON.stringify(item))
                    copy['value'] =
                      this.selectorConfig[fieldConfig.parameter[key]]
                    copy['prop'] = fieldConfig.parameter[key].toLowerCase()
                    fields.push(copy)
                  }
                }
              }
            } else {
              //选择器和对话框之外的其他搜索条件
              fields.push(item)
            }
          } else {
            //选择器和对话框之外的其他搜索条件
            fields.push(item)
          }
        })
        if (isSearchBtn) {
          utils
            .validateForm(this, this.searchFormScope)
            .then((result) => {
              //管理端预览搜索事件
              this.$parent.$parent.$emit(
                'advance-search',
                fields,
                isSearchBtn,
                isOftenUsed
              )
              //应用端搜索事件
              this.$emit('application-search', fields, isSearchBtn)
            })
            .catch((items) => {
              if (items && items.length) {
                if (this.isMobile) {
                  const errorItem = items.filter((it) => it.field)
                  this.$notify({
                    type: 'danger',
                    message: `有${errorItem.length}个字段未通过校验，请正确填写表单内容。`,
                  })
                } else {
                  this.$message.error(
                    `有${items.length}个字段未通过校验，请正确填写表单内容。`
                  )
                }
              } else {
                if (this.isMobile) {
                  this.$notify({
                    type: 'danger',
                    message: '请检查查询字段的配置是否正确',
                  })
                } else {
                  this.$message.error('请检查查询字段的配置是否正确')
                }
              }
              this.multipleTemplateTableloading = false
            })
            .finally(() => {
              this.multipleTemplateTableloading = false
            })
        } else {
          this.$parent.$parent.$emit('advance-search', fields, isSearchBtn)
          this.$emit('application-search', fields, isSearchBtn)
        }
        sessionStorage.setItem('tableSearchFormType', false)
      },
      reset() {
        this.selectorConfig = {}
        if (this.formModelExpression) {
          Object.keys(this.data[this.formModelExpression]).forEach((key) => {
            this.$set(
              this.data[this.formModelExpression],
              key,
              this.defaultData[key] ? this.defaultData[key] : ''
            )
          })
        }
        this.fieldVms.forEach((vm) => {
          vm.$emit('input-reset')
        })
        this.$nextTick(() => {
          this.search()
        })
      },
      save() {
        this.$refs.saveOftenSearch.showDialog()
      },
    },
  }
</script>
<style lang="scss" scoped>
  .search-panel__container {
    width: 100%;
    overflow: auto !important;
    // max-height: 180px;
    max-height: 144px;
    @include base-scrollbar;
  }
  .search-panel__row {
    min-width: 800px;
  }
  .flex-search__group {
    margin: 0 0 8px 0;
    width: 170px;
    display: inline-block;
  }
  .search-btn__wrap {
    // position: relative;
    // text-align: left;
    .search-btn__wrap_search {
      margin-left: 8px;
    }
    ::v-deep {
      .el-button {
        font-size: 14px;
        i {
          font-size: 16px;
        }
      }
      .el-button--small {
        padding: 7px 8px;
      }
    }
  }
  .mobile-search__container {
    max-height: calc(80vh - 110px);
    min-height: calc(40vh - 110px);
    overflow-x: hidden !important;
    //隐藏滚动条
    &::-webkit-scrollbar {
      width: 0;
      background-color: transparent;
    }
    /*火狐下隐藏滚动条*/
    scrollbar-width: none;
    .search-panel__row {
      min-width: unset;
      ::v-deep {
        .search-field__container {
          display: flex;
          flex-direction: column;
          height: unset;
        }
        .field-label-panel {
          width: calc(100% - 32px) !important;
          padding: 8px 16px;
          .search-field-label {
            max-width: unset !important;
            font-size: 14px;
            color: #262626;
            line-height: 22px;
            &::after {
              content: '';
            }
          }
        }
        .field-input-panel {
          width: calc(100% - 32px) !important;
          padding: 0px 16px 16px;
          .mobile-input-field .van-field__control {
            text-align: left;
            background-color: #f9f9f9;
            padding: 0 8px;
            &::placeholder {
              color: #bfbfbf;
            }
          }
          .van-cell--clickable:active {
            background-color: #f9f9f9;
          }
          .van-cell__value {
            justify-content: flex-start;
          }
          .mobile-input-box,
          .mobile-search--select,
          .mobile-cell__wrap {
            height: 44px;
            display: flex;
            align-items: center;
            border-radius: 8px;
            background: #f9f9f9;
            .placeholder-class {
              color: #bfbfbf;
              font-size: 14px;
            }
            .van-cell {
              background-color: #f9f9f9;
              .van-cell__value {
                padding: 0 8px;
              }
            }
            .mobile-number-input {
              width: calc(100% - 8px);
              padding-right: 8px;
              .van-stepper__input {
                width: calc(100% - 60px);
              }
            }
            .mobile-number-wrap {
              width: 100%;
            }
          }
          .mobile-date {
            height: unset;
            width: calc(100% - 8px);
            padding-left: 8px;
            .mobile-start,
            .mobile-end {
              .date-value__box {
                line-height: 12px;
              }
              .cell-close {
                font-size: 14px;
              }
            }
          }
          .mobile-search--select,
          .mobile-cell__wrap {
            .mobile-select__wrap,
            .van-cell {
              min-height: 44px;
              border-radius: 8px;
              .right-arrow {
                color: #8c8c8c;
                padding-top: 8px; //右间距因为旋转了90°所以设置padding-top
              }
            }
          }
        }
      }
    }
    ::v-deep {
      .mobile-field-tail__wrap {
        left: 0;
        .el-form-item__error {
          bottom: -18px;
          right: auto;
        }
      }
    }
  }
</style>
