import XEUtils from 'xe-utils';
import UtilTools from '../../tools/utils';
import DomTools from '../../tools/dom';

const cellType = 'footer';

function mergeFooterMethod(mergeFooterList, _rowIndex, _columnIndex) {
  for (let mIndex = 0; mIndex < mergeFooterList.length; mIndex++) {
    const { row: mergeRowIndex, col: mergeColIndex, rowspan: mergeRowspan, colspan: mergeColspan } = mergeFooterList[mIndex];
    if (mergeColIndex > -1 && mergeRowIndex > -1 && mergeRowspan && mergeColspan) {
      if (mergeRowIndex === _rowIndex && mergeColIndex === _columnIndex) {
        return { rowspan: mergeRowspan, colspan: mergeColspan };
      }
      if (_rowIndex >= mergeRowIndex && _rowIndex < mergeRowIndex + mergeRowspan && _columnIndex >= mergeColIndex && _columnIndex < mergeColIndex + mergeColspan) {
        return { rowspan: 0, colspan: 0 };
      }
    }
  }
}

export default {
  name: 'TablePlusFooter',
  props: {
    footerTableData: Array,
    tableColumn: Array,
    fixedColumn: Array,
    fixedType: String,
    size: String
  },
  mounted() {
    const { $parent: $tablePlus, $el, $refs, fixedType } = this;
    const { elemStore } = $tablePlus;
    const prefix = `${fixedType || 'main'}-footer-`;
    elemStore[`${prefix}wrapper`] = $el;
    elemStore[`${prefix}table`] = $refs.table;
    elemStore[`${prefix}colgroup`] = $refs.colgroup;
    elemStore[`${prefix}list`] = $refs.tfoot;
    elemStore[`${prefix}xSpace`] = $refs.xSpace;
  },
  destroyed() {
    const { $parent: $tablePlus, fixedType } = this;
    const { elemStore } = $tablePlus;
    const prefix = `${fixedType || 'main'}-footer-`;
    elemStore[`${prefix}wrapper`] = null;
    elemStore[`${prefix}table`] = null;
    elemStore[`${prefix}colgroup`] = null;
    elemStore[`${prefix}list`] = null;
    elemStore[`${prefix}xSpace`] = null;
  },
  render(h) {
    let { _e, $parent: $tablePlus, fixedType, fixedColumn, tableColumn, footerTableData } = this;
    const {
      $listeners: tableListeners,
      tId,
      footerRowClassName,
      footerCellClassName,
      footerRowStyle,
      footerCellStyle,
      footerAlign: allFooterAlign,
      mergeFooterList,
      footerSpanMethod,
      align: allAlign,
      scrollXLoad,
      columnKey,
      columnOpts,
      showFooterOverflow: allColumnFooterOverflow,
      currentColumn,
      overflowX,
      scrollbarWidth,
      tooltipOpts,
      visibleColumn,
      expandColumn
    } = $tablePlus;
    // 如果是使用优化模式
    if (fixedType) {
      // 如果存在展开行使用全量渲染
      if (!expandColumn && (scrollXLoad || allColumnFooterOverflow)) {
        if (!mergeFooterList.length || !footerSpanMethod) {
          tableColumn = fixedColumn;
        } else {
          tableColumn = visibleColumn;
        }
      } else {
        tableColumn = visibleColumn;
      }
    }
    return h('div', {
      class: ['el-table-plus--footer-wrapper', fixedType ? `fixed-${fixedType}--wrapper` : 'body--wrapper'],
      attrs: {
        xid: tId
      },
      on: {
        scroll: this.scrollEvent
      }
    }, [
      fixedType ? _e() : h('div', {
        class: 'table-plus-body--x-space',
        ref: 'xSpace'
      }),
      h('table', {
        class: 'el-table-plus--footer',
        attrs: {
          xid: tId,
          cellspacing: 0,
          cellpadding: 0,
          border: 0
        },
        ref: 'table'
      }, [
        /**
         * 列宽
         */
        h('colgroup', {
          ref: 'colgroup'
        }, tableColumn.map((column, $columnIndex) => {
          return h('col', {
            attrs: {
              name: column.id
            },
            key: $columnIndex
          });
        }).concat(scrollbarWidth ? [
          h('col', {
            attrs: {
              name: 'col_gutter'
            }
          })
        ] : [])),
        /**
         * 底部
         */
        h('tfoot', {
          ref: 'tfoot'
        }, footerTableData.map((list, _rowIndex) => {
          const $rowIndex = _rowIndex;
          return h('tr', {
            class: ['table-plus-footer--row', footerRowClassName ? XEUtils.isFunction(footerRowClassName) ? footerRowClassName({ $table: $tablePlus, _rowIndex, $rowIndex, fixed: fixedType, type: cellType }) : footerRowClassName : ''],
            style: footerRowStyle ? (XEUtils.isFunction(footerRowStyle) ? footerRowStyle({ $table: $tablePlus, _rowIndex, $rowIndex, fixed: fixedType, type: cellType }) : footerRowStyle) : null
          }, tableColumn.map((column, $columnIndex) => {
            const { type, showFooterOverflow, footerAlign, align, footerClassName } = column;
            const showAllTip = tooltipOpts.showAll || tooltipOpts.enabled;
            const isColGroup = column.children && column.children.length;
            const fixedHiddenColumn = fixedType ? column.fixed !== fixedType && !isColGroup : column.fixed && overflowX;
            const footOverflow = XEUtils.isUndefined(showFooterOverflow) || XEUtils.isNull(showFooterOverflow) ? allColumnFooterOverflow : showFooterOverflow;
            const footAlign = footerAlign || align || allFooterAlign || allAlign;
            let showEllipsis = footOverflow === 'ellipsis';
            const showTitle = footOverflow === 'title';
            const showTooltip = footOverflow === true || footOverflow === 'tooltip';
            let hasEllipsis = showTitle || showTooltip || showEllipsis;
            const attrs = { colid: column.id };
            const tfOns = {};
            const columnIndex = $tablePlus.getColumnIndex(column);
            const _columnIndex = $tablePlus.getVTColumnIndex(column);
            const itemIndex = _columnIndex;
            const params = { $table: $tablePlus, $grid: $tablePlus.xegrid, _rowIndex, $rowIndex, column, columnIndex, $columnIndex, _columnIndex, itemIndex, items: list, fixed: fixedType, type: cellType, data: footerTableData };
            // 虚拟滚动不支持动态高度
            if (scrollXLoad && !hasEllipsis) {
              showEllipsis = hasEllipsis = true;
            }
            if (showTitle || showTooltip || showAllTip) {
              tfOns.mouseenter = evnt => {
                if (showTitle) {
                  DomTools.updateCellTitle(evnt.currentTarget, column);
                } else if (showTooltip || showAllTip) {
                  $tablePlus.triggerFooterTooltipEvent(evnt, params);
                }
              };
            }
            if (showTooltip || showAllTip) {
              tfOns.mouseleave = evnt => {
                if (showTooltip || showAllTip) {
                  $tablePlus.handleTargetLeaveEvent(evnt);
                }
              };
            }
            if (tableListeners['footer-cell-click']) {
              tfOns.click = evnt => {
                $tablePlus.emitEvent('footer-cell-click', Object.assign({ cell: evnt.currentTarget }, params), evnt);
              };
            }
            if (tableListeners['footer-cell-dblclick']) {
              tfOns.dblclick = evnt => {
                $tablePlus.emitEvent('footer-cell-dblclick', Object.assign({ cell: evnt.currentTarget }, params), evnt);
              };
            }
            // 合并行或列
            if (mergeFooterList.length) {
              const spanRest = mergeFooterMethod(mergeFooterList, _rowIndex, _columnIndex);
              if (spanRest) {
                const { rowspan, colspan } = spanRest;
                if (!rowspan || !colspan) {
                  return null;
                }
                if (rowspan > 1) {
                  attrs.rowspan = rowspan;
                }
                if (colspan > 1) {
                  attrs.colspan = colspan;
                }
              }
            } else if (footerSpanMethod) {
              // 自定义合并方法
              const { rowspan = 1, colspan = 1 } = footerSpanMethod(params) || {};
              if (!rowspan || !colspan) {
                return null;
              }
              if (rowspan > 1) {
                attrs.rowspan = rowspan;
              }
              if (colspan > 1) {
                attrs.colspan = colspan;
              }
            }
            return h('td', {
              class: ['table-plus-footer--column', column.id, {
                [`col--${footAlign}`]: footAlign,
                [`col--${type}`]: type,
                'col--last': $columnIndex === tableColumn.length - 1,
                'fixed--hidden': fixedHiddenColumn,
                'col--ellipsis': hasEllipsis,
                'col--current': currentColumn === column
              }, UtilTools.getClass(footerClassName, params), UtilTools.getClass(footerCellClassName, params)],
              attrs,
              style: footerCellStyle ? (XEUtils.isFunction(footerCellStyle) ? footerCellStyle(params) : footerCellStyle) : null,
              on: tfOns,
              key: columnKey || columnOpts.useKey ? column.id : $columnIndex
            }, [
              h('div', {
                class: ['table-plus-cell', {
                  'c--title': showTitle,
                  'c--tooltip': showTooltip,
                  'c--ellipsis': showEllipsis
                }]
              }, column.renderFooter(h, params))
            ]);
          }).concat(scrollbarWidth ? [
            h('td', {
              class: 'table-plus-footer--gutter col--gutter'
            })
          ] : []));
        }))
      ])
    ]);
  },
  methods: {
    /**
     * 滚动处理
     * 如果存在列固定左侧，同步更新滚动状态
     * 如果存在列固定右侧，同步更新滚动状态
     */
    scrollEvent(evnt) {
      const { $parent: $tablePlus, fixedType } = this;
      const { $refs, scrollXLoad, triggerScrollXEvent, lastScrollLeft } = $tablePlus;
      const { tableHeader, tableBody, tableFooter, validTip } = $refs;
      const headerElem = tableHeader ? tableHeader.$el : null;
      const footerElem = tableFooter ? tableFooter.$el : null;
      const bodyElem = tableBody.$el;
      const scrollLeft = footerElem ? footerElem.scrollLeft : 0;
      const isX = scrollLeft !== lastScrollLeft;
      $tablePlus.lastScrollLeft = scrollLeft;
      $tablePlus.lastScrollTime = Date.now();
      if (headerElem) {
        headerElem.scrollLeft = scrollLeft;
      }
      if (bodyElem) {
        bodyElem.scrollLeft = scrollLeft;
      }
      if (scrollXLoad && isX) {
        triggerScrollXEvent(evnt);
      }
      if (isX && validTip && validTip.visible) {
        validTip.updatePlacement();
      }
      $tablePlus.emitEvent('scroll', { type: cellType, fixed: fixedType, scrollTop: bodyElem.scrollTop, scrollLeft, isX, isY: false }, evnt);
    }
  }
};
