<template>
  <el-form
    class="search-form"
    :inline="isInline"
    :label-width="width"
    :label-position="labelPosition"
  >
    <el-form-item
      v-for="({
        isEmpty = true, key, type, prop, label, labelWidth, placeholder, candidate, filterable=false, withoutAll=false, collapseTags=false,
        clearable=false, multiple=false, multipleLimit=0, changeCb, inputLimitCallback, slotName, dateType='date', rangeSeparator,
        doubleIsInline = true, maxlength = 255, pickerOptions, limit, required = false
      }) in config"
      :required="required"
      :key="label"
      :label="showLabel ? label : ''"
      :label-width="labelWidth || width"
      style="margin-right: 10px"
    >
      <el-input
        v-if="type === 'input'"
        :placeholder="placeholder ? placeholder : showLabel ? '请输入' : label"
        :value="formData[prop]"
        :maxlength="maxlength"
        @input="val => handleInput(val, prop, inputLimitCallback)"
      />
      <div
        v-if="type === 'doubleInput'"
        :class="doubleIsInline ? 'form-double-inline': ''"
      >
        <el-input
          @input="val => handleInput(val, prop[0], inputLimitCallback)"
          :value="formData[prop[0]]"
          :placeholder="(placeholder || [])[0] || '请输入'"
        />
        <el-input
          :placeholder="(placeholder || [])[1] || '请输入'"
          :value="formData[prop[1]]"
          @input="val => handleInput(val, prop[1], inputLimitCallback)"
        />
      </div>
      <el-select
        v-if="type === 'select'"
        :value="formData[prop]"
        :placeholder="placeholder ? placeholder : showLabel ? '请输入' : label"
        :clearable="clearable"
        @input="val => handleInput(val, prop)"
        @change="(...args) => changeCb && changeCb(...args)"
        :filterable="filterable"
        :multiple="multiple"
        :multiple-limit="multipleLimit"
        :collapse-tags="collapseTags"
      >
        <el-option
          v-if="!withoutAll"
          value=""
          :label="showLabel ? '全部' : label"
        />
        <el-option
          v-for="({name, value, code, id}) in candidate"
          :key="value || code || id"
          :value="value || code || id"
          :label="name"
        />
      </el-select>
      <el-date-picker
        v-if="type === 'datePicker'"
        @input="val => handleInput(val, prop)"
        @change="(...args) => changeCb && changeCb(...args)"
        :value="formData[prop]"
        format="yyyy-MM-dd"
        value-format="yyyy-MM-dd"
        :type="dateType"
        :range-separator="rangeSeparator || '到'"
        :placeholder="dateType == 'date' ? placeholder || '选择日期' : '选择日期范围'"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        :picker-options="pickerOptions"
      />
      <div
        v-if="type === 'doubleDatePicker'"
        :class="doubleIsInline ? 'form-double-inline': ''"
      >
        <el-date-picker
          @input="val => handleInput(val, prop[0], '', key)"
          @change="(...args) => changeCb && changeCb(...args)"
          :value="formData[prop[0]]"
          value-format="yyyy-MM-dd"
          format="yyyy-MM-dd"
          type="date"
          :editable="false"
          :placeholder="(placeholder || [])[0] || '开始日期'"
          :picker-options="pickerOptions?.start || genStartDateDisabledOptions(formData[prop[1]], limit)"
        />
        <el-date-picker
          @input="val => handleInput(val, prop[1], '', key)"
          @change="(...args) => changeCb && changeCb(...args)"
          :value="formData[prop[1]]"
          value-format="yyyy-MM-dd"
          format="yyyy-MM-dd"
          type="date"
          :editable="false"
          :placeholder="(placeholder || [])[1] || '结束日期'"
          :picker-options="pickerOptions?.end || genEndDateDisabledOptions(formData[prop[0]], limit)"
        />
        <el-checkbox
          :value="checkedIds[key]"
          v-if="isEmpty"
          @change="(value) => handelIsEmpty(prop, value, key)"
          class="is-empty"
        >
          空白
        </el-checkbox>
      </div>
      <slot
        v-if="type === 'slot'"
        :name="slotName"
      />
    </el-form-item>
    <span v-if="isShowSearchBtn">
      <el-button
        class="search"
        @click="handleSearch"
        type="primary"
      >{{ searchText }}</el-button>
      <el-button
        v-if="showClear"
        @click="handleClearParams"
      >{{ clearText }}</el-button>
    </span>
  </el-form>
</template>

<script>
import { genStartDateDisabledOptions, genEndDateDisabledOptions } from '../helper';

export default {
  name: 'SearchForm',
  props: {
    labelPosition: {
      default: 'right',
      type: String
    },
    isShowSearchBtn: {
      default: true,
      type: Boolean
    },
    isInline: {
      default: false,
      type: Boolean
    },
    config: {
      required: true,
      type: Array
    },
    width: {
      default: '100px',
      type: String
    },
    formData: {
      required: true
    },
    showClear: {
      default: true,
      type: Boolean
    },
    showLabel: {
      default: true,
      type: Boolean
    },
    ownerClear: {
      type: Function
    },
    resetCheckedIds: {
      type: Boolean
    },
    searchText: {
      default: '搜索',
      type: String
    },
    clearText: {
      default: '清除',
      type: String
    }
  },
  data () {
    return {
      visible: true,
      initialData: {},
      checkedIds: {}
    }
  },
  watch: {
    resetCheckedIds () {
      this.config.filter(c => c.type === 'doubleDatePicker').map(t => t.key).forEach(k => {
        this.$set(this.checkedIds, k, false)
      })
    }
  },
  mounted () {
    this.initialData = Object.freeze({ ...this.formData })
  },
  methods: {
    genStartDateDisabledOptions,
    genEndDateDisabledOptions,
    handleInput (val, prop, inputLimitCallback, key) {
      if (inputLimitCallback && !inputLimitCallback(val)) return false
      if (val) {
        this.$set(this.checkedIds, key, false)
      }
      this.$emit('update:formData', { ...this.formData, [prop]: val })
      this.$emit('isPickerEmpty', this.checkedIds)
    },

    handleSearch () {
      this.$emit('search', this.formData)
    },

    handelIsEmpty (prop, value, key) {
      if (value) {
        // eslint-disable-next-line
        this.formData[prop[0]] = '';
        // eslint-disable-next-line
        this.formData[prop[1]] = '';
      }
      this.$set(this.checkedIds, key, value)
      this.$emit('isPickerEmpty', this.checkedIds)
    },

    handleClearParams () { // 父组件可以通过调用 `this.$refs[xx].handleClearParams()` 来清空表单数据
      if (this.ownerClear && typeof this.ownerClear === 'function') {
        this.ownerClear()
        return
      }
      Object.keys(this.checkedIds).forEach((k) => {
        this.checkedIds[k] = false
      })
      this.$emit('update:formData', { ...this.formData, ...this.initialData })
      this.$emit('clear')
    },

    handleFormClose () {
      this.visible = false;
    },
  }
}
</script>
<style scoped lang="less">
.form-double-inline {
  display: flex;
  & .el-input {
    &:not(:first-child) {
      margin-left: 4px;
    }
  }
  & .el-date-editor{
    &:not(:first-child){
      margin-left: 4px;
    }
  }
}
</style>
