"use strict";

var _mapInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/map");

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.lastClickCell = void 0;
exports.rangeSelection = rangeSelection;
exports.rangeSelectionKey = void 0;

var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));

var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));

var _findIndex = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/find-index"));

var _slice = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/slice"));

var _utils = require("../../utils");

var _others = require("../../utils/others");

var _rxjs = require("rxjs");

var _operators = require("rxjs/operators");

var _styles = require("../../base/styles");

var _classnames = _interopRequireDefault(require("classnames"));

var rangeSelectionKey = 'rangeSelection';
exports.rangeSelectionKey = rangeSelectionKey;
var lastClickCell = 'lastClickCell';
exports.lastClickCell = lastClickCell;

function rangeSelection(opts) {
  return function step(pipeline) {
    var SCROLL_SIZE = 30;
    var tableBody = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.tableBody;

    if (!tableBody) {
      return pipeline;
    }

    var columns = pipeline.getColumns();

    var rangeSelectedChange = function rangeSelectedChange(rangeSelection) {
      var _a;

      pipeline.setStateAtKey(rangeSelectionKey, rangeSelection);
      (_a = opts === null || opts === void 0 ? void 0 : opts.rangeSelectedChange) === null || _a === void 0 ? void 0 : _a.call(opts, rangeSelection);
    }; // if (!pipeline.getFeatureOptions(rangeSelectionKey)) {
    //   pipeline.setFeatureOptions(rangeSelectionKey, {
    //     optionKey: rangeSelectionKey,
    //     rangeSelectedChange: rangeSelectedChange
    //   })
    // }


    var setRangeSelection = function setRangeSelection(startDragCell, draggingCell) {
      if (!startDragCell || !draggingCell || isSameCell(startDragCell, draggingCell)) return;
      var rangeColumns = getRangeColumns(startDragCell, draggingCell, columns);
      var isTopToBottom = startDragCell.rowIndex <= draggingCell.rowIndex;
      var rangeSelection = {
        startRow: isTopToBottom ? startDragCell.rowIndex : startDragCell.rowIndex + startDragCell.rowSpan - 1,
        endRow: isTopToBottom ? draggingCell.rowIndex + draggingCell.rowSpan - 1 : draggingCell.rowIndex,
        columns: rangeColumns,
        startColumn: startDragCell.column
      };
      rangeSelectedChange(rangeSelection);
    };

    var shiftKeySelect = function shiftKeySelect(event) {
      var target = event.target;
      var clickCell = getTargetCell(target, columns);

      if (clickCell) {
        if (event.shiftKey) {
          var _lastClickCell = pipeline.getStateAtKey(lastClickCell);

          if (_lastClickCell) {
            setRangeSelection(_lastClickCell, clickCell);
          } else {
            // 第一次进来就按住shift键，这时候要记住点击的单元格
            pipeline.setStateAtKey(lastClickCell, clickCell);
          }
        } else {
          pipeline.setStateAtKey(lastClickCell, clickCell);
          rangeSelectedChange(null);
        }
      }
    };

    var onMouseDown = function onMouseDown(mouseDownEvent) {
      if (mouseDownEvent.button !== 0 || !(0, _utils.isElementInEventPath)(tableBody, mouseDownEvent.nativeEvent)) return; // mouseDownEvent.preventDefault()
      // shift + 点击选中

      shiftKeySelect(mouseDownEvent);
      var target = mouseDownEvent.target;
      var startDragCell = getTargetCell(target, columns);
      var mousemove$ = (0, _rxjs.fromEvent)(window, 'mousemove');
      var mouseup$ = (0, _rxjs.fromEvent)(window, 'mouseup');
      var tableBodyClientRect = tableBody.getBoundingClientRect();

      var updateScrollPosition = function updateScrollPosition(client) {
        var clientX = client.clientX,
            clientY = client.clientY;
        var left = tableBodyClientRect.left,
            top = tableBodyClientRect.top,
            height = tableBodyClientRect.height,
            width = tableBodyClientRect.width;

        if (clientX + SCROLL_SIZE >= left + width) {
          pipeline.ref.current.domHelper.virtual.scrollLeft += SCROLL_SIZE;
        }

        if (clientX - SCROLL_SIZE <= left) {
          pipeline.ref.current.domHelper.virtual.scrollLeft -= SCROLL_SIZE;
        }

        if (clientY + SCROLL_SIZE >= top + height) {
          pipeline.ref.current.domHelper.tableBody.scrollTop += SCROLL_SIZE;
        }

        if (clientY + SCROLL_SIZE <= top) {
          pipeline.ref.current.domHelper.tableBody.scrollTop -= SCROLL_SIZE;
        }
      };

      var rangeSelected$ = mousemove$.pipe((0, _mapInstanceProperty(_operators))(function (mouseMoveEvent) {
        var target = mouseMoveEvent.target || mouseMoveEvent.srcElement;
        var draggingCell = getTargetCell(target, columns);
        var client = {
          clientX: mouseMoveEvent.clientX,
          clientY: mouseMoveEvent.clientY
        };
        updateScrollPosition(client);
        return {
          startDragCell: startDragCell,
          draggingCell: draggingCell
        };
      }), (0, _operators.takeUntil)(mouseup$));
      rangeSelected$.subscribe(function (_ref) {
        var startDragCell = _ref.startDragCell,
            draggingCell = _ref.draggingCell;
        setRangeSelection(startDragCell, draggingCell);
      });
    };

    var onKeyDown = function onKeyDown(e) {
      if (!(0, _utils.isElementInEventPath)(tableBody, e.nativeEvent)) return;

      if ((e.ctrlKey || e.metaKey) && e.key === 'a') {
        var rowLen = pipeline.getDataSource().length;

        if (columns.length && rowLen) {
          opts.preventkDefaultOfKeyDownEvent !== false && e.preventDefault();
          rangeSelectedChange({
            startRow: 0,
            endRow: rowLen - 1,
            columns: columns,
            startColumn: columns[0]
          });
        }
      }
    };

    pipeline.addTableProps({
      onMouseDown: onMouseDown,
      onKeyDown: onKeyDown,
      tabIndex: -1
    }); // todo: 后面可以把mousedown放到一个流里面

    return pipeline.mapColumns((0, _utils.makeRecursiveMapper)(function (col) {
      var _context;

      var rangeSelection = pipeline.getStateAtKey(rangeSelectionKey);
      if (!rangeSelection || (0, _findIndex.default)(_context = rangeSelection.columns).call(_context, function (selectedCol) {
        return selectedCol.code === col.code;
      }) === -1) return col;
      var prevGetCellProps = col.getCellProps;
      return (0, _extends2.default)((0, _extends2.default)({}, col), {
        getCellProps: function getCellProps(value, record, rowIndex) {
          var _cx;

          var prevCellProps = prevGetCellProps === null || prevGetCellProps === void 0 ? void 0 : prevGetCellProps(value, record, rowIndex);
          var startRow = rangeSelection.startRow,
              endRow = rangeSelection.endRow,
              columns = rangeSelection.columns;
          var startIndex = startRow < endRow ? startRow : endRow;
          var endIndex = startRow < endRow ? endRow : startRow;
          var startCol = columns[0];
          var endCol = columns[columns.length - 1];
          var match = rowIndex >= startIndex && rowIndex <= endIndex;
          var className = (0, _classnames.default)((_cx = {}, (0, _defineProperty2.default)(_cx, _styles.Classes.tableCellRangeSelected, match), (0, _defineProperty2.default)(_cx, _styles.Classes.tableCellRangeTop, rowIndex === startIndex), (0, _defineProperty2.default)(_cx, _styles.Classes.tableCellRangeLeft, col.code === startCol.code && match), (0, _defineProperty2.default)(_cx, _styles.Classes.tableCellRangeBottom, rowIndex === endIndex), (0, _defineProperty2.default)(_cx, _styles.Classes.tableCellRangeRight, col.code === endCol.code && match), _cx));
          return (0, _utils.mergeCellProps)(prevCellProps, {
            className: className
          });
        }
      });
    }));
  };
}

function getTargetCell(target, columns) {
  while (target) {
    if (target.getAttribute('data-role') === 'table-cell') {
      var _ret = function () {
        var columnCode = target.getAttribute('data-code');
        var column = (0, _others.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
          }
        };
      }();

      if ((0, _typeof2.default)(_ret) === "object") return _ret.v;
    }

    target = target.parentElement;
  }

  return null;
}

function isSameCell(cell1, cell2) {
  return cell1.rowIndex === cell2.rowIndex && cell1.code === cell2.code;
}

function getRangeColumns(startCell, endCell, columns) {
  var flatColumns = (0, _utils.collectNodes)(columns, 'leaf-only');
  var startIndex = (0, _findIndex.default)(flatColumns).call(flatColumns, function (col) {
    return col.code === startCell.code;
  });
  var endIndex = (0, _findIndex.default)(flatColumns).call(flatColumns, function (col) {
    return col.code === endCell.code;
  });

  if (startIndex < endIndex) {
    return (0, _slice.default)(flatColumns).call(flatColumns, startIndex, endIndex + 1);
  } else {
    return (0, _slice.default)(flatColumns).call(flatColumns, endIndex, startIndex + 1);
  }
}