<template>
  <div>
    <el-form :model="queryForm" ref="form" :size="size" :inline="true" :label-width="labelWidth">
      <el-form-item v-for="item in validMenus" :key="item.prop" :label="item.label" :prop="item.prop" :label-width="item.labelWidth">
        <!-- 输入框 -->
        <el-input v-if="item.type === 'text'" v-model="queryForm[item.prop]" placeholder="请输入" clearable
          :style="itemStyle(item)" />
        <!-- 选择 -->
        <el-select v-else-if="item.type === 'select'" v-model="queryForm[item.prop]" placeholder="请选择" clearable
          :multiple="item.multiple" filterable :loading="item._loading" :style="itemStyle(item)">
          <el-option v-for="option in getItemOptions(item)" :key="option[item.optionsProp] || option.value || option"
            :label="option[item.optionsLabel] || option.label || option"
            :value="option[item.optionsProp] || option.value || option" />
        </el-select>
        <NomalSelect v-else-if="item.type === 'normalselect'" v-model="queryForm[item.prop]"
        :multiple="item.multiple" :apiMethod="item.optionsMethod" :labelKey="item.optionsLabel"
        :valueKey="item.optionsProp" pageAble :style="itemStyle(item)"></NomalSelect>
        <!-- 日期选择器 -->
        <el-date-picker v-else-if="item.type === 'date'" v-model="queryForm[item.prop]" type="date"
          value-format="yyyy-MM-dd" placeholder="选择日期" clearable :style="itemStyle(item)" />
        <!-- 日期范围选择器 -->
        <el-date-picker v-else-if="item.type === 'daterange'" v-model="queryForm[item.prop]" type="daterange"
          range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" clearable
          :style="itemStyle(item)" />
      </el-form-item>
      <slot></slot>
      <el-form-item>
        <el-popover placement="bottom" trigger="click" v-model="moreCheck.visible" @show="menuCheckShow">
          <el-button slot="reference" size="mini" style="margin-right: 10px;" v-if="showMore">更多<i
              class="el-icon-d-arrow-right"></i></el-button>
          <el-checkbox :indeterminate="moreCheck.isIndeterminate" v-model="moreCheck.checkAll"
            @change="handleCheckAllChange">全选</el-checkbox>
          <el-checkbox-group v-model="moreCheck.checkedMenu" :min="1" @change="handleCheckedChange">
            <el-checkbox v-for="item in menus" :label="item.prop" :key="item.prop"
              style="display: block;margin-top: 8px;">{{ item.label }}</el-checkbox>
          </el-checkbox-group>
          <div style="margin-top: 10px;display: flex;justify-content: space-between;">
            <el-button size="mini" @click="moreCheck.visible = false">取消</el-button>
            <el-button type="primary" size="mini" @click="confirmCheck">确定</el-button>
          </div>

        </el-popover>

        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
// menus示例
// menus: [
//       {
//           label: '搜索1', // 标签名
//           prop: 'search1', // 绑定字段
//           type: 'text', // 类型
//           default: '', //默认值
//         },
//         {
//           label: '搜索2',
//           prop: 'search2',
//           type: 'select',
//           options: ['和辉煌', 'ggg'],
//           optionsMethod: () => {
          //   return new Promise((resolve) => {
          //     setTimeout(() => {
          //       resolve([
          //         { id: 1, name: '和辉煌' },
          //         { id: 2, name: 'ggg' },
          //       ]);
          //     }, 3000);
          //   });
          // },
//           optionsProp: 'id',
//           optionsLabel: 'name',
//           multiple: true,
//         },
//         {
//           label: '搜索3',
//           prop: 'search3',
//           type: 'date',
//         },
//         {
//           label: '搜索4',
//           prop: 'search4',
//           type: 'daterange',
//         }
//       ],
export default {
  name: 'SearchBlock',
  props: {
    menus: {
      type: Array,
      default: () => []
    },
    // 查询条件
    query: {
      type: Object,
      default: () => { }
    },
    size: {
      type: String,
      default: 'small'
    },
    labelWidth: {
      type: String,
      default: '68px'
    },
    // 默认展示的搜索项数量
    count: {
      type: Number,
      default: 4
    }
  },
  model: {
    prop: 'query',
    event: 'change'
  },
  data() {
    return {
      queryForm: {},
      moreCheck: {
        visible: false,
        checkAll: false,
        checkedMenu: [],
        isIndeterminate: true
      }
    }
  },
  computed: {
    // 展示的搜索选项
    validMenus() {
      return this.menus.filter(item => item._show);
    },
    // 是否展示更多按钮
    showMore() {
      return this.menus && this.menus.length > this.count;
    }
  },
  watch: {
    meuns: {
      handler(val) {
        let showCount = this.menus?.filter(item => item._show)?.length;
        this.menus?.forEach(item => {
          if (showCount < this.count) {
            this.$set(item, '_show', true);
            showCount++;
          }
          // 判断选项时去调用optionsMethod
          if (item.type === 'select' && (!item.options || item.options.length === 0)  && item.optionsMethod) {
            this.$set(item, '_loading', true);
            item.optionsMethod().then(res => {
              this.$set(item, 'options', res || []);
              this.$set(item, '_loading', false);
            }).catch(() => {
              this.$set(item, '_loading', false)
            });
          }
        });
        this.refreshQueryForm();
      },
      immediate: true,
    }
  },
  methods: {
    getItemOptions(item) {
      if (item.options && item.options.length > 0) {
        return item.options;
      }
      if (item.getOptions) {
        return item.getOptions() || [];
      }
      return [];
    },
    refreshQueryForm() {
      this.menus?.forEach(item => {
        const defaultValue = item.default === undefined ? null : item.default;
        // 更新搜索表单数据
        if (item._show) {
          this.$set(this.queryForm, item.prop, this.queryForm[item.prop] || this.query[item.prop] || defaultValue);
        } else {
          this.$set(this.queryForm, item.prop, defaultValue);
        }
      });
    },
    resetQueryForm() {
      this.queryForm = {};
      this.menus?.forEach(item => {
        // 重置搜索表单数据
        this.$set(this.queryForm, item.prop, item.default === undefined ? null : item.default);
      });
    },
    itemStyle(item) {
      if (item.type === 'date') {
        return { width: '140px' };
      }
      if (item.type === 'daterange') {
        return { width: '280px' };
      }

      return {};
    },
    handleQuery() {
      // console.log('搜索组件参数：', this.queryForm);
      this.$emit('change', this.queryForm);
    },
    resetQuery() {
      this.resetQueryForm();
      // console.log('搜索组件参数：', this.queryForm);
      this.$emit('change', this.queryForm);
    },
    // 展示搜索项选择
    menuCheckShow() {
      this.moreCheck.checkedMenu = this.menus.filter(item => item._show).map(item => item.prop);
      this.moreCheck.isIndeterminate = this.moreCheck.checkedMenu.length > 0 && this.moreCheck.checkedMenu.length < this.menus.length;
      this.moreCheck.checkAll = this.moreCheck.checkedMenu.length === this.menus.length;
    },
    // 全选搜索项
    handleCheckAllChange(val) {
      this.moreCheck.checkedMenu = val ? this.menus.map(item => item.prop) : [this.menus[0].prop];
      this.moreCheck.isIndeterminate = !val;
    },
    // 选择搜索项
    handleCheckedChange(value) {
      let checkedCount = value.length;
      this.moreCheck.checkAll = checkedCount === this.menus.length;
      this.moreCheck.isIndeterminate = checkedCount > 0 && checkedCount < this.menus.length;
    },
    // 确定选择搜索项
    confirmCheck() {
      this.menus.forEach(item => {
        this.$set(item, '_show', this.moreCheck.checkedMenu.includes(item.prop));
      });
      this.refreshQueryForm();
      this.moreCheck.visible = false;
    }
  }
}
</script>

<style></style>
