<template>
  <div>
    <el-dialog
      width="80%"
      :title="title"
      :visible.sync="visible"
      :append-to-body="true"
      :destroy-on-close="true"
      @close="handleBeforeClose"
      @open="handleOpenDialog"
    >
      <div v-if="subtitle" style="margin-bottom: 10px; margin-top: -15px" v-text="subtitle"></div>
      <avue-crud
        ref="crud"
        class="listSelect"
        v-model="crudObj"
        :data.sync="crudData"
        :option.sync="crudOption"
        :page.sync="crudPage"
        @current-change="currentChange"
        @current-row-change="currentRowChange"
        @refresh-change="refreshChange"
        @search-change="searchChange"
        @search-reset="searchReset"
        @selection-change="selectionChange"
        @size-change="sizeChange"
      >
        <template slot="menuLeft">
          <el-button type="primary" size="small" plain @click.stop="doAction()">
            {{ btnText }}
          </el-button>
        </template>

        <!-- 自定义 slots -->
        <template
          v-for="customSlotItem in customSlotItems"
          :slot="customSlotItem.prop"
          slot-scope="{ row }"
        >
          <slot
            v-if="customSlotItem && customSlotItem.prop"
            :slot-scope="row"
            :name="customSlotItem.slotName"
          />
        </template>
      </avue-crud>
    </el-dialog>
  </div>
</template>
<script>
import { DIALOG_TABLE_MAX_HEIGHT } from '../../../lib/const';
import { ft } from '../../../lib/utils';
export default {
  name: 'selectDialogTable',
  props: {
    btnText: { type: String, default: ft('i18n_common_confirm', '确定') }, // 保存按钮文字
    title: { type: String, default: '' }, // dialog 标题
    subtitle: { type: String, default: '' }, // dialog 副标题
    dialogVisible: { type: Boolean, default: false }, // dialog显隐

    // 表格的列配置
    column: {
      type: Array,
      default: () => {
        return [];
      }
    },

    // customSlots: 自定义 slots, 只输出 slot name, 具体内容由使用都定义(不在组件内部定义), 最多支持 10 个自定义 slot
    customSlots: {
      type: Array,
      default: function () {
        return [];
      }
    },
    // 表格的数据
    data: {
      type: Array,
      default: () => {
        return [];
      }
    },
    // 表格的分页配置
    page: {
      type: Object,
      default: () => {
        return { total: 0, currentPage: 1, pageSize: 10 };
      }
    },
    // 表格的查询参数（点击搜索时，更新当前参数）
    queryParam: {
      type: Object,
      default: () => {
        return {};
      }
    },
    // 表格的分页参数(点击搜索，切换分页，切换每页展示条数时，更新当前参数)
    pageParam: {
      type: Object,
      default: () => {
        return { pageNo: 1, currentPage: 1, pageSize: 10 };
      }
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },

    beforeCloseFn: {
      type: Function,
      default: null
    },

    searchResetFn: {
      type: Function,
      default: null
    }
  },
  data() {
    return {
      visible: this.dialogVisible,
      multipleSelection: [],
      crudObj: {},
      crudData: [],
      crudOption: {
        highlightCurrentRow: true,
        selection: false,
        addBtn: false,
        columnBtn: false,
        refreshBtn: false,
        searchShow: false,
        menu: false,
        index: true,
        indexLabel: '#',
        border: true,
        maxHeight: DIALOG_TABLE_MAX_HEIGHT,
        emptyText: ft('i18n_common_no_data', '暂无数据'),
        column: []
      },
      crudPage: {
        total: 0,
        currentPage: 1,
        pageSize: 10
      },
      crudQueryParam: {},
      crudMultiple: false,
      currentRow: null,

      customSlotItems: []
    };
  },
  created() {
    this.crudOption.column = this.column;
    this.crudData = this.data;
    this.crudPage = this.page;
    this.crudQueryParam = this.queryParam;
    this.crudMultiple = this.multiple;
    this.crudOption.selection = this.multiple;
    this.crudOption.highlightCurrentRow = !this.multiple;
  },
  watch: {
    column: function (newValue) {
      this.crudOption.column = newValue;
    },

    customSlots: {
      handler: function (newVal, oldVar) {
        if (newVal) {
          this.handleCustomSlotsChanged(newVal);
        }
      },
      immediate: true,
      deep: true
    },

    data: function (newValue) {
      this.crudData = newValue;
    },

    dialogVisible: function (newValue) {
      this.visible = newValue;
    },

    page: {
      handler(newValue) {
        this.crudPage = newValue;
      },
      deep: true,
      immediate: true
    },

    visible: function (newValue) {
      this.$emit('update:dialogVisible', newValue);
    }

    // // TODO:直接修改对象中的属性不会触发此事件，而父对象传入的参数也会对应改变
    // crudQueryParam: function(newValue) {
    //   this.$emit('update:queryParam', newValue);
    // },
    // // TODO:直接修改对象中的属性不会触发此事件，而父对象传入的参数也会对应改变
    // page: function(newValue) {
    //   this.$emit('update:pageParam', newValue);
    // }
  },
  methods: {
    currentChange(page) {
      this.page.currentPage = page;
      this.$emit('handleList', this.queryParam, this.page);
    },

    currentRowChange(row) {
      if (!this.crudMultiple) {
        const list = [];
        list.push(row);
        this.multipleSelection = list;
      }
    },

    doAction() {
      const selectItems = this.multipleSelection;

      // if (selectItems.length < 1) {
      //   this.$message.warning('请选择至少一条数据');
      //   return;
      // }

      this.multipleSelection = [];
      this.$refs.crud.selectClear();
      this.$refs.crud.setCurrentRow();
      this.$emit('ok', selectItems);
      this.visible = false;
    },

    handleBeforeClose() {
      if (typeof this.beforeCloseFn === 'function') {
        this.beforeCloseFn();
      }
    },

    handleCustomSlotsChanged(customSlots = []) {
      for (const customSlot of customSlots) {
        if (customSlot && customSlot.prop && customSlot.slotName) {
          this.customSlotItems.push(customSlot || {});
        }
      }
    },

    handleOpenDialog() {
      this.$emit('handleList', this.queryParam, this.page);
    },

    refreshChange() {
      this.page.currentPage = 1;
      this.$emit('handleList', this.queryParam, this.page);
    },

    searchChange(params, done) {
      const searchFormObj = {};

      const columns = this.$refs.crud.columnOption;

      for (const column of columns) {
        if (column.search) {
          searchFormObj[column.prop] = '';
        }
      }

      for (const formProp in searchFormObj) {
        delete this.crudQueryParam[formProp];
      }

      this.page.currentPage = 1;

      Object.assign(this.crudQueryParam, params);

      this.$emit('handleList', this.queryParam, this.page);

      done();
    },

    searchReset() {
      typeof this.searchResetFn === 'function' && this.searchResetFn();
    },

    selectionChange(list) {
      if (this.crudMultiple) {
        this.multipleSelection = list;
      }
    },

    sizeChange(pageSize) {
      this.page.currentPage = 1;
      this.page.pageSize = pageSize;
      this.$emit('handleList', this.queryParam, this.page);
    },

    toggleSelection(rows) {
      if (rows) {
        rows.forEach((row) => {
          this.$refs.crud.toggleRowSelection(row);
        });
      } else {
        this.$refs.crud.clearSelection();
      }
    }
  }
};
</script>
<style>
.listSelect .el-collapse-item__header {
  display: none;
}
.listSelect .el-dialog__body {
  padding-top: 5px;
}
.listSelect .el-collapse {
  border-top: 0;
  border-bottom: 0;
}
</style>
