import _defineProperty from "@babel/runtime-corejs3/helpers/defineProperty";
import _extends from "@babel/runtime-corejs3/helpers/extends";
import _toConsumableArray from "@babel/runtime-corejs3/helpers/toConsumableArray";
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
import _findIndexInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find-index";
import _sliceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/slice";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import { mergeCellProps, makeRecursiveMapper, isElementInEventPath, collectNodes } from '../../utils';
import { findByTree } from '../../utils/others';
import { fromEvent } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { Classes } from '../../base/styles';
import cx from 'classnames';
export var rangeSelectionKey = 'rangeSelection';
export var lastClickCellKey = 'lastClickCell';
var startSelectedCellRangesKey = 'startSelectedCellRanges';
var SCROLL_OFFSET = 30;
export function rangeSelection(opts) {
  return function step(pipeline) {
    var tableBody = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.tableBody;
    var tableFooter = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.tableFooter;
    var artTable = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.artTable;
    if (!tableBody) {
      return pipeline;
    }
    var columns = pipeline.getColumns();
    var dataSource = pipeline.getDataSource();
    var rangeSelectedChange = function rangeSelectedChange(rangeSelection, isFinished) {
      var _a;
      if (isFinished) {
        pipeline.setFeatureOptions(startSelectedCellRangesKey, rangeSelection);
      }
      pipeline.setStateAtKey(rangeSelectionKey, rangeSelection);
      (_a = opts === null || opts === void 0 ? void 0 : opts.rangeSelectedChange) === null || _a === void 0 ? void 0 : _a.call(opts, rangeSelection, isFinished);
    };
    var setRangeSelection = function setRangeSelection(startDragCell, draggingCell, isFinished) {
      if (!startDragCell || !draggingCell) return;
      var rangeColumns = getRangeColumns(startDragCell, draggingCell, columns);
      var _getRangeSelectionRow = getRangeSelectionRowInfo(startDragCell, draggingCell, dataSource),
        startRow = _getRangeSelectionRow.startRow,
        endRow = _getRangeSelectionRow.endRow,
        footerRowRange = _getRangeSelectionRow.footerRowRange;
      var cellRange = {
        startRow: startRow,
        endRow: endRow,
        columns: rangeColumns,
        startColumn: startDragCell.column,
        footerRowRange: footerRowRange
      };
      var cellRanges = pipeline.getFeatureOptions(startSelectedCellRangesKey) ? _toConsumableArray(pipeline.getFeatureOptions(startSelectedCellRangesKey)) : [];
      if (isCellRangeSingleCell([cellRange])) {
        var singleCellRangeId = getCellRangeId(cellRange);
        cellRanges = _filterInstanceProperty(cellRanges).call(cellRanges, function (item) {
          return getCellRangeId(item) !== singleCellRangeId;
        });
      }
      cellRanges.push(cellRange);
      if (isCellRangeSingleCell(cellRanges)) {
        artTable.classList.remove(cx(Classes.rangeSelection));
      } else {
        artTable.classList.add(cx(Classes.rangeSelection));
      }
      rangeSelectedChange(cellRanges, isFinished);
    };
    var shiftKeySelect = function shiftKeySelect(event) {
      var target = event.target;
      var clickCell = getTargetCell(target, columns);
      if (clickCell) {
        var _lastClickCell = pipeline.getFeatureOptions(lastClickCellKey);
        if (_lastClickCell) {
          setRangeSelection(_lastClickCell, clickCell, true);
        } else {
          // 第一次进来就按住shift键，这时候要记住点击的单元格
          pipeline.setFeatureOptions(lastClickCellKey, clickCell);
        }
      }
    };
    var updateScrollPosition = function updateScrollPosition(client) {
      var clientX = client.clientX,
        clientY = client.clientY;
      var tableBodyClientRect = tableBody.getBoundingClientRect();
      var left = tableBodyClientRect.left,
        top = tableBodyClientRect.top,
        height = tableBodyClientRect.height,
        width = tableBodyClientRect.width;
      if (clientX + SCROLL_OFFSET >= left + width) {
        pipeline.ref.current.domHelper.virtual.scrollLeft += SCROLL_OFFSET;
      }
      if (clientX - SCROLL_OFFSET <= left) {
        pipeline.ref.current.domHelper.virtual.scrollLeft -= SCROLL_OFFSET;
      }
      if (clientY + SCROLL_OFFSET >= top + height) {
        pipeline.ref.current.domHelper.tableBody.scrollTop += SCROLL_OFFSET;
      }
      if (clientY + SCROLL_OFFSET <= top) {
        pipeline.ref.current.domHelper.tableBody.scrollTop -= SCROLL_OFFSET;
      }
    };
    var setStartSelectedCellRanges = function setStartSelectedCellRanges(isCtrlKey, isShiftKey) {
      if (opts === null || opts === void 0 ? void 0 : opts.suppressMultiRangeSelection) {
        pipeline.setFeatureOptions(startSelectedCellRangesKey, []);
        return;
      }
      // ctrl 和shift 同时按时，优先生效shift
      // 没有点击ctrl 或者shift时，每次点击开始时都清空选中范围
      if (!isCtrlKey && !isShiftKey) {
        pipeline.setFeatureOptions(startSelectedCellRangesKey, []);
      }
      // shift 点击框选，要保留之前的选中结果。最新的框选范围覆盖最后一次的框选范围
      if (isShiftKey) {
        var _startDragCellRanges = pipeline.getFeatureOptions(startSelectedCellRangesKey) ? _toConsumableArray(pipeline.getFeatureOptions(startSelectedCellRangesKey)) : [];
        _startDragCellRanges.pop();
        pipeline.setFeatureOptions(startSelectedCellRangesKey, _startDragCellRanges);
      }
    };
    var onMouseDown = function onMouseDown(mouseDownEvent) {
      if (mouseDownEvent.button !== 0 || !(isElementInEventPath(tableBody, mouseDownEvent.nativeEvent) || isElementInEventPath(tableFooter, mouseDownEvent.nativeEvent))) return;
      // mouseDownEvent.preventDefault()
      var isCtrlKey = mouseDownEvent.ctrlKey || mouseDownEvent.metaKey;
      var isShiftKey = mouseDownEvent.shiftKey;
      var target = mouseDownEvent.target;
      var startDragCell = getTargetCell(target, columns);
      if (!startDragCell) return;
      // 每次点击时先确认初始生效的框选范围
      setStartSelectedCellRanges(isCtrlKey, isShiftKey);
      if (isShiftKey) {
        shiftKeySelect(mouseDownEvent);
        return;
      }
      pipeline.setFeatureOptions(lastClickCellKey, startDragCell);
      var draggingCell = startDragCell;
      var mousemove$ = fromEvent(window, 'mousemove');
      var mouseup$ = fromEvent(window, 'mouseup');
      var rangeSelected$ = mousemove$.pipe(map(function (mouseMoveEvent) {
        var target = mouseMoveEvent.target || mouseMoveEvent.srcElement;
        draggingCell = getTargetCell(target, columns);
        var client = {
          clientX: mouseMoveEvent.clientX,
          clientY: mouseMoveEvent.clientY
        };
        if (!(draggingCell === null || draggingCell === void 0 ? void 0 : draggingCell.isFooterCell)) {
          updateScrollPosition(client);
        }
        return {
          startDragCell: startDragCell,
          draggingCell: draggingCell
        };
      }), takeUntil(mouseup$));
      rangeSelected$.subscribe({
        next: function next(_ref) {
          var startDragCell = _ref.startDragCell,
            draggingCell = _ref.draggingCell;
          setRangeSelection(startDragCell, draggingCell, false);
        },
        complete: function complete() {
          setRangeSelection(startDragCell, draggingCell, true);
        }
      });
    };
    var onKeyDown = function onKeyDown(e) {
      if (!(isElementInEventPath(tableBody, e.nativeEvent) || isElementInEventPath(tableFooter, e.nativeEvent))) return;
      if ((e.ctrlKey || e.metaKey) && e.key === 'a') {
        var rowLen = pipeline.getDataSource().length;
        var footerDataSource = pipeline.getFooterDataSource() || [];
        // 焦点位于可编辑的单元格内不做全选
        if (columns.length && rowLen && !getElementEditable(e.target)) {
          opts.preventkDefaultOfKeyDownEvent !== false && e.preventDefault();
          artTable.classList.add(cx(Classes.rangeSelection));
          rangeSelectedChange([{
            startRow: 0,
            endRow: rowLen - 1,
            columns: collectNodes(columns, 'leaf-only'),
            startColumn: columns[0],
            footerRowRange: footerDataSource.length > 0 ? {
              startRow: 0,
              endRow: footerDataSource.length - 1
            } : null
          }], true);
        }
      }
    };
    pipeline.addTableProps({
      onMouseDown: onMouseDown,
      onKeyDown: onKeyDown,
      tabIndex: -1
    }); // todo: 后面可以把mousedown放到一个流里面
    return pipeline.mapColumns(makeRecursiveMapper(function (col) {
      var cellRanges = pipeline.getStateAtKey(rangeSelectionKey) || [];
      var prevGetCellProps = col.getCellProps;
      return _extends(_extends({}, col), {
        getCellProps: function getCellProps(value, record, rowIndex) {
          var prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex);
          var isFooterCell = record[pipeline.getFeatureOptions('footerRowMetaKey')];
          if (!cellRanges.some(function (cellRange) {
            return isCellInRange(cellRange, rowIndex, col, isFooterCell);
          })) return prevCellProps;
          var className = getCellRangesClassName(cellRanges, {
            isFooterCell: isFooterCell,
            rowIndex: rowIndex,
            col: col,
            record: record
          });
          return mergeCellProps(prevCellProps, {
            className: className
          });
        }
      });
    }));
  };
}
function getTargetCell(target, columns) {
  var _loop = function _loop() {
      if (target.getAttribute('data-role') === 'table-cell') {
        var columnCode = target.getAttribute('data-code');
        var column = findByTree(columns, function (item, index) {
          return item.code === columnCode;
        });
        if (!column) return {
          v: null
        };
        return {
          v: {
            rowIndex: parseInt(target.getAttribute('data-rowindex')),
            rowSpan: parseInt(target.getAttribute('rowspan') || 1),
            code: columnCode,
            column: column,
            isFooterCell: isEleInFooter(target)
          }
        };
      }
      target = target.parentElement;
    },
    _ret;
  while (target) {
    _ret = _loop();
    if (_ret) return _ret.v;
  }
  return null;
}
function isSameCell(cell1, cell2) {
  return cell1.rowIndex === cell2.rowIndex && cell1.code === cell2.code && cell1.isFooterCell === cell2.isFooterCell;
}
function isEleInFooter(target) {
  while (target && !target.classList.contains(Classes.artTable)) {
    if (target.classList.contains(Classes.tableFooter)) {
      return true;
    }
    target = target.parentElement;
  }
  return false;
}
function getRangeColumns(startCell, endCell, columns) {
  var flatColumns = collectNodes(columns, 'leaf-only');
  var startIndex = _findIndexInstanceProperty(flatColumns).call(flatColumns, function (col) {
    return col.code === startCell.code;
  });
  var endIndex = _findIndexInstanceProperty(flatColumns).call(flatColumns, function (col) {
    return col.code === endCell.code;
  });
  if (startIndex < endIndex) {
    return _sliceInstanceProperty(flatColumns).call(flatColumns, startIndex, endIndex + 1);
  } else {
    return _sliceInstanceProperty(flatColumns).call(flatColumns, endIndex, startIndex + 1);
  }
}
function getRangeSelectionRowInfo(startCell, endCell, dataSource) {
  var footerRowRange = null;
  var startRow = -1;
  var endRow = -1;
  var _getCellRangeRow = getCellRangeRow(startCell, endCell),
    _startRow = _getCellRangeRow.startRow,
    _endRow = _getCellRangeRow.endRow;
  // 两个单元格都在表体
  if (!startCell.isFooterCell && !endCell.isFooterCell) {
    startRow = _startRow;
    endRow = _endRow;
  } else if (startCell.isFooterCell && endCell.isFooterCell) {
    // 两个单元格都在表底
    footerRowRange = {
      startRow: _startRow,
      endRow: _endRow
    };
  } else {
    // 一个单元格在表体，一个在表底
    if (startCell.isFooterCell) {
      startRow = dataSource.length - 1;
      endRow = endCell.rowIndex;
      footerRowRange = {
        startRow: startCell.rowIndex,
        endRow: 0
      };
    } else {
      startRow = startCell.rowIndex;
      endRow = dataSource.length - 1;
      footerRowRange = {
        startRow: 0,
        endRow: endCell.rowIndex
      };
    }
  }
  return {
    startRow: startRow,
    endRow: endRow,
    footerRowRange: footerRowRange
  };
}
/**
 * 获取框选范围的起始结束行
 * @param startCell 起始单元格
 * @param endCell 结束单元格
 * @returns
 */
function getCellRangeRow(startCell, endCell) {
  if (isSameCell(startCell, endCell)) {
    return {
      startRow: startCell.rowIndex,
      endRow: startCell.rowIndex
    };
  }
  var isTopToBottom = startCell.rowIndex <= endCell.rowIndex;
  var startRow = isTopToBottom ? startCell.rowIndex : startCell.rowIndex + startCell.rowSpan - 1;
  var endRow = isTopToBottom ? endCell.rowIndex + endCell.rowSpan - 1 : endCell.rowIndex;
  return {
    startRow: startRow,
    endRow: endRow
  };
}
/**
 * 框选范围是否只包含单个单元格
 * @param cellRanges
 * @returns
 */
function isCellRangeSingleCell(cellRanges) {
  if (cellRanges.length !== 1) return false;
  var _cellRanges$ = cellRanges[0],
    startRow = _cellRanges$.startRow,
    endRow = _cellRanges$.endRow,
    columns = _cellRanges$.columns,
    footerRowRange = _cellRanges$.footerRowRange;
  var isBodySingleCell = !footerRowRange && startRow === endRow && columns.length === 1;
  var isFooterSingleCell = startRow === -1 && footerRowRange.startRow === footerRowRange.endRow && columns.length === 1;
  return isBodySingleCell || isFooterSingleCell;
}
function getRowIndex(startRow, endRow) {
  var isReverse = startRow > endRow;
  var startRowIndex = isReverse ? endRow : startRow;
  var endRowIndex = isReverse ? startRow : endRow;
  return {
    startRowIndex: startRowIndex,
    endRowIndex: endRowIndex
  };
}
function getFooterRowIndex(footerRowRange) {
  if (footerRowRange) {
    return getRowIndex(footerRowRange.startRow, footerRowRange.endRow);
  }
  return {
    startRowIndex: -1,
    endRowIndex: -1
  };
}
function getElementEditable(target) {
  var _context;
  if (!target) return;
  if (_includesInstanceProperty(_context = ['input', 'textarea']).call(_context, target.tagName.toLowerCase())) {
    if (target.type === 'checkbox') return;
    return !target.disabled && !target.readOnly;
  }
}
/**
 * 判断单元格是否在框选范围内
 * @param cellRange
 * @param rowIndex
 * @param col
 * @param isFooterCell
 * @returns
 */
function isCellInRange(cellRange, rowIndex, col, isFooterCell) {
  var startRow = cellRange.startRow,
    endRow = cellRange.endRow,
    columns = cellRange.columns,
    footerRowRange = cellRange.footerRowRange;
  var isColInRanges = _findIndexInstanceProperty(columns).call(columns, function (item) {
    return item.code === col.code;
  }) !== -1;
  if (!isColInRanges) return false;
  var _getRowIndex = getRowIndex(startRow, endRow),
    startRowIndex = _getRowIndex.startRowIndex,
    endRowIndex = _getRowIndex.endRowIndex;
  var _getFooterRowIndex = getFooterRowIndex(footerRowRange),
    footerStartRowIndex = _getFooterRowIndex.startRowIndex,
    footerEndRowIndex = _getFooterRowIndex.endRowIndex;
  var bodyMatch = !isFooterCell && rowIndex >= startRowIndex && rowIndex <= endRowIndex;
  var footerMatch = isFooterCell && footerRowRange && rowIndex >= footerStartRowIndex && rowIndex <= footerEndRowIndex;
  var isRowInRange = footerMatch || bodyMatch;
  return isRowInRange;
}
/**
 * 获取框选范围唯一标识
 * @param {*} cellRange
 * @returns
 */
export function getCellRangeId(cellRange) {
  var startRow = cellRange.startRow,
    endRow = cellRange.endRow,
    footerRowRange = cellRange.footerRowRange,
    columns = cellRange.columns;
  var _getRowIndex2 = getRowIndex(startRow, endRow),
    startRowIndex = _getRowIndex2.startRowIndex,
    endRowIndex = _getRowIndex2.endRowIndex;
  var _getFooterRowIndex2 = getFooterRowIndex(footerRowRange),
    footerStartRowIndex = _getFooterRowIndex2.startRowIndex,
    footerEndRowIndex = _getFooterRowIndex2.endRowIndex;
  var firstColId = columns[0].code;
  var endColId = columns[columns.length - 1].code;
  return startRowIndex + '_' + endRowIndex + '_' + footerStartRowIndex + '_' + footerEndRowIndex + '_' + firstColId + '_' + endColId;
}
/**
 * 获取框选范围中单元格的样式
 * @param cellRanges
 * @param param1
 * @returns
 */
function getCellRangesClassName(cellRanges, _ref2) {
  var isFooterCell = _ref2.isFooterCell,
    rowIndex = _ref2.rowIndex,
    col = _ref2.col,
    record = _ref2.record;
  var _getMatchBorderStyle = getMatchBorderStyle(cellRanges, {
      isFooterCell: isFooterCell,
      rowIndex: rowIndex,
      col: col,
      record: record
    }),
    matchCellRangeTop = _getMatchBorderStyle.matchCellRangeTop,
    matchCellRangeLeft = _getMatchBorderStyle.matchCellRangeLeft,
    matchCellRangeBottom = _getMatchBorderStyle.matchCellRangeBottom,
    matchCellRangeRight = _getMatchBorderStyle.matchCellRangeRight;
  var isSingleCell = isCellRangeSingleCell(cellRanges);
  var className = cx(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, Classes.tableCellRangeSingleCell, isSingleCell), Classes.tableCellRangeSelected, !isSingleCell), Classes.tableCellRangeTop, !isSingleCell && matchCellRangeTop), Classes.tableCellRangeLeft, !isSingleCell && matchCellRangeLeft), Classes.tableCellRangeBottom, !isSingleCell && matchCellRangeBottom), Classes.tableCellRangeRight, !isSingleCell && matchCellRangeRight));
  return className;
}
function getMatchBorderStyle(cellRanges, _ref3) {
  var isFooterCell = _ref3.isFooterCell,
    rowIndex = _ref3.rowIndex,
    col = _ref3.col,
    record = _ref3.record;
  return cellRanges.reduce(function (obj, cellRange) {
    if (!isCellInRange(cellRange, rowIndex, col, isFooterCell)) return obj;
    var startRow = cellRange.startRow,
      endRow = cellRange.endRow,
      columns = cellRange.columns,
      footerRowRange = cellRange.footerRowRange;
    var _getRowIndex3 = getRowIndex(startRow, endRow),
      startRowIndex = _getRowIndex3.startRowIndex,
      endRowIndex = _getRowIndex3.endRowIndex;
    var _getFooterRowIndex3 = getFooterRowIndex(footerRowRange),
      footerStartRowIndex = _getFooterRowIndex3.startRowIndex,
      footerEndRowIndex = _getFooterRowIndex3.endRowIndex;
    var startCol = columns[0];
    var endCol = columns[columns.length - 1];
    var matchCellRangeTop = isFooterCell ? startRowIndex !== -1 ? false : rowIndex === footerStartRowIndex : rowIndex === startRowIndex;
    var matchCellRangeLeft = col.code === startCol.code;
    var matchCellRangeBottom = isFooterCell ? rowIndex === footerEndRowIndex : footerRowRange ? false : rowIndex === endRowIndex;
    var matchCellRangeRight = col.code === endCol.code;
    // 如果样式已经匹配上了，就不需要再取计算的样式
    obj.matchCellRangeTop = obj.matchCellRangeTop || matchCellRangeTop;
    obj.matchCellRangeLeft = obj.matchCellRangeLeft || matchCellRangeLeft;
    obj.matchCellRangeBottom = obj.matchCellRangeBottom || matchCellRangeBottom;
    obj.matchCellRangeRight = obj.matchCellRangeRight || matchCellRangeRight;
    return obj;
  }, {
    matchCellRangeTop: false,
    matchCellRangeLeft: false,
    matchCellRangeBottom: false,
    matchCellRangeRight: false
  });
}