import Table from '../../table-plus/src/table';
import XEUtils from 'xe-utils';
import GlobalConfig from '../../table-plus/src/v-table/src/conf';
import vSize from '../../table-plus/src/mixins/size';
import VTable from '../../table-plus/src/v-table';
import UtilTools, { isEnableConf } from '../../table-plus/src/tools/utils';
import DomTools, {
  getOffsetHeight,
  getPaddingTopBottomSize
} from '../../table-plus/src/tools/dom';
import { GlobalEvent } from '../../table-plus/src/tools/event';
import { warnLog, errLog } from '../../table-plus/src/tools/log';
import { getSlotVNs } from '../../table-plus/src/tools/vn';

const methods = {};
const propKeys = Object.keys(Table.props);

function getTableOns(_vm) {
  const { $listeners, proxyConfig, proxyOpts } = _vm;
  const ons = {};
  XEUtils.each($listeners, (cb, type) => {
    ons[type] = (...args) => {
      _vm.$emit(type, ...args);
    };
  });
  if (proxyConfig) {
    if (proxyOpts.sort) {
      ons['sort-change'] = _vm.sortChangeEvent;
    }
    if (proxyOpts.filter) {
      ons['filter-change'] = _vm.filterChangeEvent;
    }
  }
  return ons;
}

Object.keys(Table.methods).forEach((name) => {
  methods[name] = function(...args) {
    return this.$refs.tablePro && this.$refs.tablePro[name](...args);
  };
});

export default {
  name: 'ElTablePro',
  mixins: [vSize],
  props: {
    ...Table.props,
    columns: Array,
    pagerConfig: [Boolean, Object],
    proxyConfig: Object,
    toolbar: [Boolean, Object],
    toolbarConfig: [Boolean, Object],
    formConfig: [Boolean, Object],
    zoomConfig: Object,
    size: {
      type: String,
      default: () => GlobalConfig.grid.size || GlobalConfig.size
    }
  },
  provide() {
    return {
      $xegrid: this
    };
  },
  data() {
    return {
      tableLoading: false,
      isZMax: false,
      tableData: [],
      pendingRecords: [],
      filterData: [],
      formData: {},
      sortData: [],
      tZindex: 0,
      tablePage: {
        total: 0,
        pageSize: GlobalConfig.pager.pageSize || 10,
        currentPage: 1
      }
    };
  },
  computed: {
    isMsg() {
      return this.proxyOpts.message !== false;
    },
    proxyOpts() {
      return Object.assign({}, GlobalConfig.grid.proxyConfig, this.proxyConfig);
    },
    pagerOpts() {
      return Object.assign({}, GlobalConfig.grid.pagerConfig, this.pagerConfig);
    },
    formOpts() {
      return Object.assign({}, GlobalConfig.grid.formConfig, this.formConfig);
    },
    toolbarOpts() {
      return Object.assign(
        {},
        GlobalConfig.grid.toolbarConfig,
        this.toolbarConfig || this.toolbar
      );
    },
    zoomOpts() {
      return Object.assign({}, GlobalConfig.grid.zoomConfig, this.zoomConfig);
    },
    renderStyle() {
      return this.isZMax ? { zIndex: this.tZindex } : null;
    },
    tableExtendProps() {
      const rest = {};
      propKeys.forEach((key) => {
        rest[key] = this[key];
      });
      return rest;
    },
    tableProps() {
      const {
        isZMax,
        seqConfig,
        pagerConfig,
        loading,
        editConfig,
        proxyConfig,
        proxyOpts,
        tableExtendProps,
        tableLoading,
        tablePage,
        tableData
      } = this;
      const tableProps = Object.assign({}, tableExtendProps);
      if (isZMax) {
        if (tableExtendProps.maxHeight) {
          tableProps.maxHeight = 'auto';
        } else {
          tableProps.height = 'auto';
        }
      }
      if (proxyConfig) {
        tableProps.loading = loading || tableLoading;
        tableProps.data = tableData;
        tableProps.rowClassName = this.handleRowClassName;
        if (proxyOpts.seq && isEnableConf(pagerConfig)) {
          tableProps.seqConfig = Object.assign({}, seqConfig, {
            startIndex: (tablePage.currentPage - 1) * tablePage.pageSize
          });
        }
      }
      if (editConfig) {
        tableProps.editConfig = Object.assign({}, editConfig, {
          beforeEditMethod: this.handleBeforeEditMethod
        });
      }
      return tableProps;
    }
  },
  watch: {
    columns: {
      handler(value) {
        this.$nextTick(() => this.loadColumn(value));
      },
      deep: true
    },
    toolbar(value) {
      if (value) {
        this.initToolbar();
      }
    },
    toolbarConfig(value) {
      if (value) {
        this.initToolbar();
      }
    },
    proxyConfig() {
      this.initProxy();
    },
    pagerConfig() {
      this.initPages();
    }
  },
  created() {
    const { data, formOpts, proxyOpts, proxyConfig } = this;
    if (proxyConfig && (data || (proxyOpts.form && formOpts.data))) {
      errLog('tablePro.error.errConflicts', ['grid.data', 'grid.proxy-config']);
    }

    if (process.env.NODE_ENV === 'development') {
      if (this.toolbar) {
        warnLog('tablePro.error.delProp', [
          'grid.toolbar',
          'grid.toolbar-config'
        ]);
      }
      if (this.toolbarConfig && !XEUtils.isObject(this.toolbarConfig)) {
        warnLog('tablePro.error.errProp', [
          `grid.toolbar-config=${this.toolbarConfig}`,
          'grid.toolbar-config={}'
        ]);
      }
    }
    this.initPages();
    GlobalEvent.on(this, 'keydown', this.handleGlobalKeydownEvent);
  },
  mounted() {
    if (this.columns && this.columns.length) {
      this.loadColumn(this.columns);
    }
    this.initToolbar();
    this.initProxy();
  },
  destroyed() {
    GlobalEvent.off(this, 'keydown');
  },
  render(h) {
    const { $scopedSlots, vSize, isZMax } = this;
    return h(
      'div',
      {
        class: [
          'el-table-pro',
          {
            [`size--${vSize}`]: vSize,
            'is--animat': !!this.animat,
            'is--round': this.round,
            'is--maximize': isZMax,
            'is--loading': this.loading || this.tableLoading
          }
        ],
        style: this.renderStyle
      },
      [
        /**
         * 渲染表格
         */
        h('el-table-plus', {
          props: this.tableProps,
          on: getTableOns(this),
          scopedSlots: $scopedSlots,
          ref: 'tablePro'
        }),
        /**
         * 渲染表格底部区域
         */
        $scopedSlots.bottom
          ? h(
            'div',
            {
              ref: 'bottomWrapper',
              class: 'el-table-pro--bottom-wrapper'
            },
            $scopedSlots.bottom.call(this, { $grid: this }, h)
          )
          : null
      ]
    );
  },
  methods: {
    ...methods,
    callSlot(slotFunc, params, h, vNodes) {
      if (slotFunc) {
        const { $scopedSlots } = this;
        if (XEUtils.isString(slotFunc)) {
          slotFunc = $scopedSlots[slotFunc] || null;
        }
        if (XEUtils.isFunction(slotFunc)) {
          return getSlotVNs(slotFunc.call(this, params, h, vNodes));
        }
      }
      return [];
    },
    getParentHeight() {
      const { $el, isZMax } = this;
      return (
        (isZMax
          ? DomTools.getDomNode().visibleHeight
          : XEUtils.toNumber(getComputedStyle($el.parentNode).height)) -
        this.getExcludeHeight()
      );
    },
    /**
     * 获取需要排除的高度
     */
    getExcludeHeight() {
      const { $refs, $el, isZMax, height } = this;
      const {
        formWrapper,
        toolbarWrapper,
        topWrapper,
        bottomWrapper,
        pagerWrapper
      } = $refs;
      const parentPaddingSize =
        isZMax || height !== 'auto'
          ? 0
          : getPaddingTopBottomSize($el.parentNode);
      return (
        parentPaddingSize +
        getPaddingTopBottomSize($el) +
        getOffsetHeight(formWrapper) +
        getOffsetHeight(toolbarWrapper) +
        getOffsetHeight(topWrapper) +
        getOffsetHeight(bottomWrapper) +
        getOffsetHeight(pagerWrapper)
      );
    },
    handleRowClassName(params) {
      const rowClassName = this.rowClassName;
      const clss = [];
      if (this.pendingRecords.some((item) => item === params.row)) {
        clss.push('row--pending');
      }
      clss.push(
        rowClassName
          ? XEUtils.isFunction(rowClassName)
            ? rowClassName(params)
            : rowClassName
          : ''
      );
      return clss;
    },
    handleBeforeEditMethod(params) {
      const { editConfig } = this;
      const beforeEditMethod = editConfig
        ? editConfig.beforeEditMethod || editConfig.activeMethod
        : null;
      if (this.pendingRecords.indexOf(params.row) === -1) {
        return !beforeEditMethod || beforeEditMethod({ ...params, $grid: this });
      }
      return false;
    },
    initToolbar() {
      this.$nextTick(() => {
        const { tablePro, xToolbar } = this.$refs;
        if (tablePro && xToolbar) {
          tablePro.connect(xToolbar);
        }
      });
    },
    initPages() {
      const { tablePage, pagerConfig, pagerOpts } = this;
      const { currentPage, pageSize } = pagerOpts;
      if (pagerConfig) {
        if (currentPage) {
          tablePage.currentPage = currentPage;
        }
        if (pageSize) {
          tablePage.pageSize = pageSize;
        }
      }
    },
    initProxy() {
      const { proxyInited, proxyConfig, proxyOpts, formConfig, formOpts } = this;
      if (proxyConfig) {
        if (isEnableConf(formConfig) && proxyOpts.form && formOpts.items) {
          const formData = {};
          formOpts.items.forEach((item) => {
            const { field, itemRender } = item;
            if (field) {
              let itemValue = null;
              if (itemRender) {
                const { defaultValue } = itemRender;
                if (XEUtils.isFunction(defaultValue)) {
                  itemValue = defaultValue({ item });
                } else if (!XEUtils.isUndefined(defaultValue)) {
                  itemValue = defaultValue;
                }
              }
              formData[field] = itemValue;
            }
          });
          this.formData = formData;
        }
        if (!proxyInited && proxyOpts.autoLoad !== false) {
          this.proxyInited = true;
          this.$nextTick()
            .then(() => this.commitProxy('_init'))
            .then((rest) => {
              this.$emit('proxy-query', {
                ...rest,
                isInited: true,
                $grid: this,
                $event: new Event('init')
              });
            });
        }
      }
    },
    handleGlobalKeydownEvent(evnt) {
      const isEsc = evnt.keyCode === 27;
      if (isEsc && this.isZMax && this.zoomOpts.escRestore !== false) {
        this.triggerZoomEvent(evnt);
      }
    },
    /**
     * 提交指令，支持 code 或 button
     * @param {String/Object} code 字符串或对象
     */
    commitProxy(proxyTarget, ...args) {
      const {
        $refs,
        toolbar,
        toolbarConfig,
        toolbarOpts,
        proxyOpts,
        tablePage,
        pagerConfig,
        editRules,
        formData,
        isMsg
      } = this;
      const {
        beforeQuery,
        afterQuery,
        beforeDelete,
        afterDelete,
        beforeSave,
        afterSave,
        ajax = {},
        props: proxyProps = {}
      } = proxyOpts;
      const $tablePlus = $refs.tablePro;
      let button;
      let code;
      if (XEUtils.isString(proxyTarget)) {
        const matchObj =
          toolbarConfig || toolbar
            ? XEUtils.findTree(
              toolbarOpts.buttons,
              (item) => item.code === proxyTarget,
              { children: 'dropdowns' }
            )
            : null;
        code = proxyTarget;
        button = matchObj ? matchObj.item : null;
      } else {
        button = proxyTarget;
        code = button.code;
      }
      const btnParams = button ? button.params : null;
      switch (code) {
        case 'insert':
          return this.insert();
        case 'insert_actived':
          return this.insert().then(({ row }) => this.setActiveRow(row));
        case 'mark_cancel':
          this.triggerPendingEvent(code);
          break;
        case 'remove':
          return this.handleDeleteRow(
            code,
            'tablePro.grid.removeSelectRecord',
            () => this.removeCheckboxRow()
          );
        case 'import':
          this.importData(btnParams);
          break;
        case 'open_import':
          this.openImport(btnParams);
          break;
        case 'export':
          this.exportData(btnParams);
          break;
        case 'open_export':
          this.openExport(btnParams);
          break;
        case 'reset_custom':
          this.resetColumn(true);
          break;
        case '_init':
        case 'reload':
        case 'query': {
          const ajaxMethods = ajax.query;
          if (ajaxMethods) {
            const isInited = code === '_init';
            const isReload = code === 'reload';
            let sortList = [];
            let filterList = [];
            let pageParams = {};
            if (pagerConfig) {
              if (isInited || isReload) {
                tablePage.currentPage = 1;
              }
              if (isEnableConf(pagerConfig)) {
                pageParams = { ...tablePage };
              }
            }
            if (isInited) {
              const { sortOpts } = $tablePlus;
              let defaultSort = sortOpts.defaultSort;
              // 如果使用默认排序
              if (defaultSort) {
                if (!XEUtils.isArray(defaultSort)) {
                  defaultSort = [defaultSort];
                }
                sortList = defaultSort.map((item) => {
                  return {
                    field: item.field,
                    property: item.field,
                    order: item.order
                  };
                });
              }
              filterList = $tablePlus.getCheckedFilters();
            } else {
              if (isReload) {
                this.pendingRecords = [];
                $tablePlus.clearAll();
              } else {
                sortList = $tablePlus.getSortColumns();
                filterList = $tablePlus.getCheckedFilters();
              }
            }
            const params = {
              code,
              button,
              isInited,
              isReload,
              $grid: this,
              page: pageParams,
              sort: sortList.length ? sortList[0] : {},
              sorts: sortList,
              filters: filterList,
              form: formData,
              options: ajaxMethods
            };
            this.sortData = sortList;
            this.filterData = filterList;
            this.tableLoading = true;
            const applyArgs = [params].concat(args);
            return window.Promise.resolve(
              (beforeQuery || ajaxMethods)(...applyArgs)
            )
              .then((rest) => {
                this.tableLoading = false;
                if (rest) {
                  if (isEnableConf(pagerConfig)) {
                    const total =
                      XEUtils.get(rest, proxyProps.total || 'page.total') || 0;
                    tablePage.total = XEUtils.toNumber(total);
                    this.tableData =
                      XEUtils.get(rest, proxyProps.result || 'result') || [];
                    // 检验当前页码，不能超出当前最大页数
                    const pageCount = Math.max(
                      Math.ceil(total / tablePage.pageSize),
                      1
                    );
                    if (tablePage.currentPage > pageCount) {
                      tablePage.currentPage = pageCount;
                    }
                  } else {
                    this.tableData =
                      (proxyProps.list
                        ? XEUtils.get(rest, proxyProps.list)
                        : rest) || [];
                  }
                } else {
                  this.tableData = [];
                }
                if (afterQuery) {
                  afterQuery(...applyArgs);
                }
                return { status: true };
              })
              .catch(() => {
                this.tableLoading = false;
                return { status: false };
              });
          } else {
            if (process.env.NODE_ENV === 'development') {
              errLog('tablePro.error.notFunc', ['proxy-config.ajax.query']);
            }
          }
          break;
        }
        case 'delete': {
          const ajaxMethods = ajax.delete;
          if (ajaxMethods) {
            const selectRecords = $tablePlus.getCheckboxRecords();
            const removeRecords = selectRecords.filter(
              (row) => !$tablePlus.isInsertByRow(row)
            );
            const body = { removeRecords };
            const applyArgs = [
              {
                $grid: this,
                code,
                button,
                body,
                form: formData,
                options: ajaxMethods
              }
            ].concat(args);
            if (selectRecords.length) {
              return this.handleDeleteRow(
                code,
                'tablePro.grid.deleteSelectRecord',
                () => {
                  if (!removeRecords.length) {
                    return $tablePlus.remove(selectRecords);
                  }
                  this.tableLoading = true;
                  return window.Promise.resolve(
                    (beforeDelete || ajaxMethods)(...applyArgs)
                  )
                    .then((rest) => {
                      this.tableLoading = false;
                      this.pendingRecords = this.pendingRecords.filter(
                        (row) => removeRecords.indexOf(row) === -1
                      );
                      if (isMsg) {
                        // 检测弹窗模块
                        if (process.env.NODE_ENV === 'development') {
                          if (!VTable.modal) {
                            errLog('tablePro.error.reqModule', ['Modal']);
                          }
                        }
                        VTable.modal.message({
                          content: this.getRespMsg(
                            rest,
                            'tablePro.grid.delSuccess'
                          ),
                          status: 'success'
                        });
                      }
                      if (afterDelete) {
                        afterDelete(...applyArgs);
                      } else {
                        this.commitProxy('query');
                      }
                      return { status: true };
                    })
                    .catch((rest) => {
                      this.tableLoading = false;
                      if (isMsg) {
                        // 检测弹窗模块
                        if (process.env.NODE_ENV === 'development') {
                          if (!VTable.modal) {
                            errLog('tablePro.error.reqModule', ['Modal']);
                          }
                        }
                        VTable.modal.message({
                          id: code,
                          content: this.getRespMsg(
                            rest,
                            'tablePro.grid.operError'
                          ),
                          status: 'error'
                        });
                      }
                      return { status: false };
                    });
                }
              );
            } else {
              if (isMsg) {
                // 检测弹窗模块
                if (process.env.NODE_ENV === 'development') {
                  if (!VTable.modal) {
                    errLog('tablePro.error.reqModule', ['Modal']);
                  }
                }
                VTable.modal.message({
                  id: code,
                  content: 'tablePro.grid.selectOneRecord',
                  status: 'warning'
                });
              }
            }
          } else {
            if (process.env.NODE_ENV === 'development') {
              errLog('tablePro.error.notFunc', ['proxy-config.ajax.delete']);
            }
          }
          break;
        }
        case 'save': {
          const ajaxMethods = ajax.save;
          if (ajaxMethods) {
            const body = Object.assign(
              { pendingRecords: this.pendingRecords },
              this.getRecordset()
            );
            const {
              insertRecords,
              removeRecords,
              updateRecords,
              pendingRecords
            } = body;
            const applyArgs = [
              {
                $grid: this,
                code,
                button,
                body,
                form: formData,
                options: ajaxMethods
              }
            ].concat(args);
            // 排除掉新增且标记为删除的数据
            if (insertRecords.length) {
              body.pendingRecords = pendingRecords.filter(
                (row) => insertRecords.indexOf(row) === -1
              );
            }
            // 排除已标记为删除的数据
            if (pendingRecords.length) {
              body.insertRecords = insertRecords.filter(
                (row) => pendingRecords.indexOf(row) === -1
              );
            }
            let restPromise = window.Promise.resolve();
            if (editRules) {
              // 只校验新增和修改的数据
              restPromise = this.validate(
                body.insertRecords.concat(updateRecords)
              );
            }
            return restPromise.then((errMap) => {
              if (errMap) {
                // 如果校验不通过
                return;
              }
              if (
                body.insertRecords.length ||
                removeRecords.length ||
                updateRecords.length ||
                body.pendingRecords.length
              ) {
                this.tableLoading = true;
                return window.Promise.resolve(
                  (beforeSave || ajaxMethods)(...applyArgs)
                )
                  .then((rest) => {
                    this.tableLoading = false;
                    this.pendingRecords = [];
                    if (isMsg) {
                      // 检测弹窗模块
                      if (process.env.NODE_ENV === 'development') {
                        if (!VTable.modal) {
                          errLog('tablePro.error.reqModule', ['Modal']);
                        }
                      }
                      VTable.modal.message({
                        content: this.getRespMsg(
                          rest,
                          'tablePro.grid.saveSuccess'
                        ),
                        status: 'success'
                      });
                    }
                    if (afterSave) {
                      afterSave(...applyArgs);
                    } else {
                      this.commitProxy('query');
                    }
                    return { status: true };
                  })
                  .catch((rest) => {
                    this.tableLoading = false;
                    if (isMsg) {
                      // 检测弹窗模块
                      if (process.env.NODE_ENV === 'development') {
                        if (!VTable.modal) {
                          errLog('tablePro.error.reqModule', ['Modal']);
                        }
                      }
                      VTable.modal.message({
                        id: code,
                        content: this.getRespMsg(
                          rest,
                          'tablePro.grid.operError'
                        ),
                        status: 'error'
                      });
                    }
                    return { status: false };
                  });
              } else {
                if (isMsg) {
                  // 检测弹窗模块
                  if (process.env.NODE_ENV === 'development') {
                    if (!VTable.modal) {
                      errLog('tablePro.error.reqModule', ['Modal']);
                    }
                  }
                  VTable.modal.message({
                    id: code,
                    content: 'tablePro.grid.dataUnchanged',
                    status: 'info'
                  });
                }
              }
            });
          } else {
            if (process.env.NODE_ENV === 'development') {
              errLog('tablePro.error.notFunc', ['proxy-config.ajax.save']);
            }
          }
          break;
        }
        default: {
          const gCommandOpts = VTable.commands.get(code);
          if (gCommandOpts) {
            if (gCommandOpts.commandMethod) {
              gCommandOpts.commandMethod(
                { code, button, $grid: this, $table: $tablePlus },
                ...args
              );
            } else {
              if (process.env.NODE_ENV === 'development') {
                errLog('tablePro.error.notCommands', [code]);
              }
            }
          }
        }
      }
      return this.$nextTick();
    },
    getRespMsg(rest, defaultMsg) {
      const { props: proxyProps = {} } = this.proxyOpts;
      let msg;
      if (rest && proxyProps.message) {
        msg = XEUtils.get(rest, proxyProps.message);
      }
      return msg || defaultMsg;
    },
    handleDeleteRow(code, alertKey, callback) {
      const selectRecords = this.getCheckboxRecords();
      if (this.isMsg) {
        if (selectRecords.length) {
          return VTable.modal
            .confirm({
              id: `cfm_${code}`,
              content: alertKey,
              escClosable: true
            })
            .then((type) => {
              if (type === 'confirm') {
                return callback();
              }
            });
        } else {
          // 检测弹窗模块
          if (process.env.NODE_ENV === 'development') {
            if (!VTable.modal) {
              errLog('tablePro.error.reqModule', ['Modal']);
            }
          }
          VTable.modal.message({
            id: `msg_${code}`,
            content: 'tablePro.grid.selectOneRecord',
            status: 'warning'
          });
        }
      } else {
        if (selectRecords.length) {
          callback();
        }
      }
      return window.Promise.resolve();
    },
    getFormItems(itemIndex) {
      const { formConfig, formOpts } = this;
      const itemList = [];
      XEUtils.eachTree(
        isEnableConf(formConfig) && formOpts.items ? formOpts.items : [],
        (item) => {
          itemList.push(item);
        },
        { children: 'children' }
      );
      return XEUtils.isUndefined(itemIndex) ? itemList : itemList[itemIndex];
    },
    getPendingRecords() {
      return this.pendingRecords;
    },
    triggerToolbarCommitEvent(params, evnt) {
      const { code } = params;
      return this.commitProxy(params, evnt).then((rest) => {
        if (
          code &&
          rest &&
          rest.status &&
          ['query', 'reload', 'delete', 'save'].includes(code)
        ) {
          this.$emit(
            code === 'delete' || code === 'save'
              ? `proxy-${code}`
              : 'proxy-query',
            { ...rest, isReload: code === 'reload', $grid: this, $event: evnt }
          );
        }
      });
    },
    triggerToolbarBtnEvent(button, evnt) {
      this.triggerToolbarCommitEvent(button, evnt);
      this.$emit('toolbar-button-click', {
        code: button.code,
        button,
        $grid: this,
        $event: evnt
      });
    },
    triggerToolbarTolEvent(tool, evnt) {
      this.triggerToolbarCommitEvent(tool, evnt);
      this.$emit('toolbar-tool-click', {
        code: tool.code,
        tool,
        $grid: this,
        $event: evnt
      });
    },
    triggerPendingEvent(code) {
      const { pendingRecords, isMsg } = this;
      const selectRecords = this.getCheckboxRecords();
      if (selectRecords.length) {
        const plus = [];
        const minus = [];
        selectRecords.forEach((data) => {
          if (pendingRecords.some((item) => data === item)) {
            minus.push(data);
          } else {
            plus.push(data);
          }
        });
        if (minus.length) {
          this.pendingRecords = pendingRecords
            .filter((item) => minus.indexOf(item) === -1)
            .concat(plus);
        } else if (plus.length) {
          this.pendingRecords = pendingRecords.concat(plus);
        }
        this.clearSelection();
      } else {
        if (isMsg) {
          // 检测弹窗模块
          if (process.env.NODE_ENV === 'development') {
            if (!VTable.modal) {
              errLog('tablePro.error.reqModule', ['Modal']);
            }
          }
          VTable.modal.message({
            id: code,
            content: 'tablePro.grid.selectOneRecord',
            status: 'warning'
          });
        }
      }
    },
    pageChangeEvent(params) {
      const { proxyConfig, tablePage } = this;
      const { currentPage, pageSize } = params;
      tablePage.currentPage = currentPage;
      tablePage.pageSize = pageSize;
      this.$emit('page-change', Object.assign({ $grid: this }, params));
      if (proxyConfig) {
        this.commitProxy('query').then((rest) => {
          this.$emit('proxy-query', {
            ...rest,
            $grid: this,
            $event: params.$event
          });
        });
      }
    },
    sortChangeEvent(params) {
      const { $table, column, sortList } = params;
      const isRemote = XEUtils.isBoolean(column.remoteSort)
        ? column.remoteSort
        : $table.sortOpts.remote;
      // 如果是服务端排序
      if (isRemote) {
        this.sortData = sortList;
        if (this.proxyConfig) {
          this.tablePage.currentPage = 1;
          this.commitProxy('query').then((rest) => {
            this.$emit('proxy-query', {
              ...rest,
              $grid: this,
              $event: params.$event
            });
          });
        }
      }
      this.$emit('sort-change', Object.assign({ $grid: this }, params));
    },
    filterChangeEvent(params) {
      const { $table, filterList } = params;
      // 如果是服务端过滤
      if ($table.filterOpts.remote) {
        this.filterData = filterList;
        if (this.proxyConfig) {
          this.tablePage.currentPage = 1;
          this.commitProxy('query').then((rest) => {
            this.$emit('proxy-query', {
              ...rest,
              $grid: this,
              $event: params.$event
            });
          });
        }
      }
      this.$emit('filter-change', Object.assign({ $grid: this }, params));
    },
    submitEvent(params) {
      const { proxyConfig } = this;
      if (proxyConfig) {
        this.commitProxy('reload').then((rest) => {
          this.$emit('proxy-query', {
            ...rest,
            isReload: true,
            $grid: this,
            $event: params.$event
          });
        });
      }
      this.$emit('form-submit', Object.assign({ $grid: this }, params));
    },
    resetEvent(params) {
      const { proxyConfig } = this;
      if (proxyConfig) {
        this.commitProxy('reload').then((rest) => {
          this.$emit('proxy-query', {
            ...rest,
            isReload: true,
            $grid: this,
            $event: params.$event
          });
        });
      }
      this.$emit('form-reset', Object.assign({ $grid: this }, params));
    },
    submitInvalidEvent(params) {
      this.$emit('form-submit-invalid', Object.assign({ $grid: this }, params));
    },
    collapseEvent(params) {
      this.$nextTick(() => this.recalculate(true));
      this.$emit('form-toggle-collapse', Object.assign({ $grid: this }, params));
      this.$emit('form-collapse', Object.assign({ $grid: this }, params));
    },
    triggerZoomEvent(evnt) {
      this.zoom();
      this.$emit('zoom', {
        $grid: this,
        type: this.isZMax ? 'max' : 'revert',
        $event: evnt
      });
    },
    zoom() {
      return this[this.isZMax ? 'revert' : 'maximize']();
    },
    isMaximized() {
      return this.isZMax;
    },
    maximize() {
      return this.handleZoom(true);
    },
    revert() {
      return this.handleZoom();
    },
    handleZoom(isMax) {
      const { isZMax } = this;
      if (isMax ? !isZMax : isZMax) {
        this.isZMax = !isZMax;
        if (this.tZindex < UtilTools.getLastZIndex()) {
          this.tZindex = UtilTools.nextZIndex();
        }
      }
      return this.$nextTick()
        .then(() => this.recalculate(true))
        .then(() => this.isZMax);
    },
    getProxyInfo() {
      const { sortData, proxyConfig } = this;
      if (proxyConfig) {
        return {
          data: this.tableData,
          filter: this.filterData,
          form: this.formData,
          sort: sortData.length ? sortData[0] : {},
          sorts: sortData,
          pager: this.tablePage,
          pendingRecords: this.pendingRecords
        };
      }
      return null;
    },
    // 检查插槽
    ...(process.env.NODE_ENV === 'development'
      ? {
        loadColumn(columns) {
          const { $scopedSlots } = this;
          XEUtils.eachTree(columns, (column) => {
            if (column.scopedSlots) {
              XEUtils.each(column.scopedSlots, (func) => {
                if (!XEUtils.isFunction(func)) {
                  if (!$scopedSlots[func]) {
                    errLog('tablePro.error.notSlot', [func]);
                  }
                }
              });
            }
          });
          return this.$refs.tablePro.loadColumn(columns);
        },
        reloadColumn(columns) {
          this.clearAll();
          return this.loadColumn(columns);
        }
      }
      : null)
  }
};
