"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.ROW_DRAG_COLUMN_CODE = void 0;
exports.rowDrag = rowDrag;
exports.rowDragKey = void 0;

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

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

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

var _react = _interopRequireDefault(require("react"));

var _rxjs = require("rxjs");

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

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

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

var ROW_DRAG_COLUMN_CODE = '$_row_drag_column_&';
exports.ROW_DRAG_COLUMN_CODE = ROW_DRAG_COLUMN_CODE;
var rowDragKey = 'rowDragKey';
exports.rowDragKey = rowDragKey;
var SCROLL_OFFSET = 30;
var defaultRowDragColumn = {
  name: '拖拽列',
  code: ROW_DRAG_COLUMN_CODE,
  lock: true,
  title: '',
  width: 40,
  align: 'center',
  getCellProps: function getCellProps(value, row, rowIndex) {
    return {
      className: (0, _classnames.default)(_styles.Classes.rowDragCell)
    };
  },
  render: function render(value, row, rowIndex) {
    return /*#__PURE__*/_react.default.createElement("svg", {
      viewBox: '0 0 1024 1024',
      version: '1.1',
      xmlns: 'http://www.w3.org/1999/xlink',
      "data-icon": 'drag',
      width: '16',
      height: '16'
    }, /*#__PURE__*/_react.default.createElement("path", {
      d: 'M298.688 192a64 64 0 1 0 128 0 64 64 0 0 0-128 0z m298.624 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0zM298.688 512a64 64 0 1 0 128 0 64 64 0 0 0-128 0z m298.624 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z m-298.624 320a64 64 0 1 0 128 0 64 64 0 0 0-128 0z m298.624 0a64 64 0 1 0 128 0 64 64 0 0 0-128 0z',
      "p-id": '4278'
    }));
  }
};

function rowDrag(opt) {
  return function rowDragStep(pipeline) {
    var _context;

    var tableBody = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.tableBody;
    var artTable = pipeline.ref.current.domHelper && pipeline.ref.current.domHelper.artTable;
    if (!tableBody) return pipeline;
    var dataSource = pipeline.getDataSource();
    var rowHeight = (opt === null || opt === void 0 ? void 0 : opt.rowHeight) || 48;

    var handleDragStrat = function handleDragStrat(event) {
      var _a; // 开始拖拽


      artTable.classList.add((0, _classnames.default)(_styles.Classes.rowDragging));
      (_a = opt === null || opt === void 0 ? void 0 : opt.onDragStart) === null || _a === void 0 ? void 0 : _a.call(opt, event);
    };

    var handleDragMove = function handleDragMove(event) {
      var _a;

      (_a = opt === null || opt === void 0 ? void 0 : opt.onDragMove) === null || _a === void 0 ? void 0 : _a.call(opt, event);
      pipeline.setStateAtKey(rowDragKey, event);
    };

    var handleDragEnd = function handleDragEnd(event, isOutOfRange) {
      var _a;

      artTable.classList.remove((0, _classnames.default)(_styles.Classes.rowDragging));
      pipeline.setStateAtKey(rowDragKey, event); // 超出拖拽范围不触发dragend事件

      if (!isOutOfRange) {
        (_a = opt === null || opt === void 0 ? void 0 : opt.onDragEnd) === null || _a === void 0 ? void 0 : _a.call(opt, event);
      }
    };

    var getDragEvent = function getDragEvent(startRowInfo, endRowInfo, _ref) {
      var isFinished = _ref.isFinished,
          _ref$dragPosition = _ref.dragPosition,
          dragPosition = _ref$dragPosition === void 0 ? 'bottom' : _ref$dragPosition;
      return {
        startRowIndex: startRowInfo.rowIndex,
        startRow: startRowInfo.row,
        endRowIndex: endRowInfo.rowIndex,
        endRow: endRowInfo.row,
        dragPosition: dragPosition,
        isFinished: isFinished
      };
    };

    var updateScrollPosition = function updateScrollPosition(mouseMoveEvent) {
      if (opt === null || opt === void 0 ? void 0 : opt.suppressScrollMove) return;
      var clientY = mouseMoveEvent.clientY;
      var tableBodyClientRect = tableBody.getBoundingClientRect();
      var top = tableBodyClientRect.top,
          height = tableBodyClientRect.height;

      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 onMouseDown = function onMouseDown(mouseDownEvent) {
      var _a;

      var startRowInfo = getTargetRowInfo(mouseDownEvent.target, tableBody, dataSource);
      var endRowInfo = startRowInfo;
      if (!startRowInfo || startRowInfo.code !== rowDragColumn.code) return;
      if ((_a = opt === null || opt === void 0 ? void 0 : opt.isDisabled) === null || _a === void 0 ? void 0 : _a.call(opt, startRowInfo.row, startRowInfo.rowIndex)) return; // 默认拖拽插入的位置是向下

      var dragPosition = 'bottom';
      var isOutOfRange = false;
      var dragStartEvent = getDragEvent(startRowInfo, endRowInfo, {
        isFinished: false,
        dragPosition: 'bottom'
      });
      handleDragStrat(dragStartEvent);
      var tableWidth = tableBody.clientWidth;
      var startRowRects = startRowInfo.cell.getBoundingClientRect(); // 光标位置距离初始拖拽行的偏移量

      var startOffset = mouseDownEvent.clientY - startRowRects.y;
      var dragElement = createDragElement(startRowRects, tableWidth, rowHeight); // 可拖拽的范围

      var dragRange = getDragRange(tableBody, {
        startOffset: startOffset,
        rowHeight: startRowRects.height
      });
      var mousemove$ = (0, _rxjs.fromEvent)(window, 'mousemove');
      var mouseup$ = (0, _rxjs.fromEvent)(window, 'mouseup');
      var rowDrag$ = mousemove$.pipe((0, _mapInstanceProperty(_operators))(function (mouseMoveEvent) {
        var clientX = mouseMoveEvent.clientX,
            clientY = mouseMoveEvent.clientY;
        var tagretRow = getTargetRowInfo(mouseMoveEvent.target, tableBody, dataSource);

        if (tagretRow) {
          endRowInfo = tagretRow;
        }

        var targetRowRects = endRowInfo.cell.getBoundingClientRect(); // 判断拖拽插入的位置，拖拽框上边框位于目标行之上则向上插入，否则向下插入

        var isMoveToTop = clientY - startOffset < targetRowRects.y;
        dragPosition = isMoveToTop ? 'top' : 'bottom';
        isOutOfRange = isOutOfDragRange({
          x: clientX,
          y: clientY
        }, dragRange);
        updateScrollPosition(mouseMoveEvent); // 拖拽到底时让滚动条可以滚动

        updateDragElementPosition(dragElement, dragRange, {
          x: clientX,
          y: clientY,
          startOffset: startOffset
        });
        updateCurSorStyle(isOutOfRange);
        return {
          startRowInfo: startRowInfo,
          endRowInfo: endRowInfo,
          dragPosition: dragPosition
        };
      }), (0, _operators.takeUntil)(mouseup$));
      rowDrag$.subscribe({
        next: function next(_ref2) {
          var startRowInfo = _ref2.startRowInfo,
              endRowInfo = _ref2.endRowInfo,
              dragPosition = _ref2.dragPosition;
          var dragMoveEvent = getDragEvent(startRowInfo, endRowInfo, {
            isFinished: false,
            dragPosition: dragPosition
          });
          handleDragMove(dragMoveEvent);
        },
        complete: function complete() {
          var dragEndEvent = getDragEvent(startRowInfo, endRowInfo, {
            isFinished: true,
            dragPosition: dragPosition
          });
          handleDragEnd(dragEndEvent, isOutOfRange);
          removeDragElement(dragElement);
          removeCurSorStyle();
        }
      });
    };

    var rowDragColumn = (opt === null || opt === void 0 ? void 0 : opt.rowDragColumn) || defaultRowDragColumn;
    pipeline.setFeatureOptions('rowDragColumnKey', rowDragColumn.code);
    var nextColumns = (0, _slice.default)(_context = pipeline.getColumns()).call(_context);
    nextColumns.unshift(rowDragColumn);
    pipeline.columns(nextColumns);
    pipeline.addTableProps({
      onMouseDown: onMouseDown
    });
    pipeline.appendRowPropsGetter(function (row, rowIndex) {
      var _cx;

      var rowDragEvent = pipeline.getStateAtKey(rowDragKey) || {};
      var startRowIndex = rowDragEvent.startRowIndex,
          endRowIndex = rowDragEvent.endRowIndex,
          isFinished = rowDragEvent.isFinished,
          dragPosition = rowDragEvent.dragPosition;
      var isFooterCell = row[pipeline.getFeatureOptions('footerRowMetaKey')];
      if (isFooterCell || isFinished || rowIndex !== startRowIndex && rowIndex !== endRowIndex) return;
      var className = (0, _classnames.default)((_cx = {}, (0, _defineProperty2.default)(_cx, _styles.Classes.rowDragStart, rowIndex === startRowIndex), (0, _defineProperty2.default)(_cx, _styles.Classes.rowDragEnd, rowIndex === endRowIndex), (0, _defineProperty2.default)(_cx, _styles.Classes.rowDragEndToTop, rowIndex === endRowIndex && dragPosition === 'top'), (0, _defineProperty2.default)(_cx, _styles.Classes.rowDragEndToBottom, rowIndex === endRowIndex && dragPosition === 'bottom'), _cx));
      return {
        className: className
      };
    });
    return pipeline;
  };
}

function getTargetRowInfo(target, tableBody, record) {
  while (target && tableBody.contains(target)) {
    if (target.getAttribute('data-role') === 'table-cell') {
      var code = target.getAttribute('data-code');
      var rowIndex = parseInt(target.getAttribute('data-rowindex'));
      var row = record[rowIndex];
      var isFooterCell = isEleInFooter(target);
      if (!row || isFooterCell) return null;
      return {
        rowIndex: rowIndex,
        row: row,
        code: code,
        cell: target
      };
    }

    target = target.parentElement;
  }

  return null;
}

function isEleInFooter(target) {
  while (target && !target.classList.contains(_styles.Classes.artTable)) {
    if (target.classList.contains(_styles.Classes.tableFooter)) {
      return true;
    }

    target = target.parentElement;
  }

  return false;
}

function createDragElement(rects, tableWidth, rowHeight) {
  var _context2, _context3, _context4;

  var x = rects.x,
      y = rects.y;
  var dragMoveElement = document.createElement('div');
  dragMoveElement.className = (0, _classnames.default)(_styles.Classes.rowDragElement);
  dragMoveElement.style.cssText = (0, _concat.default)(_context2 = (0, _concat.default)(_context3 = (0, _concat.default)(_context4 = "position:fixed;z-index:9999;left:".concat(x, "px;top:")).call(_context4, y, "px;pointer-events:none;width:")).call(_context3, tableWidth, "px;height:")).call(_context2, rowHeight, "px;background:var(--primary-color);opacity: 0.1;");
  document.body.appendChild(dragMoveElement);
  return dragMoveElement;
}

function updateDragElementPosition(element, dragRange, _ref3) {
  var x = _ref3.x,
      y = _ref3.y,
      startOffset = _ref3.startOffset;
  var validPosition = getValidPosition({
    x: x,
    y: y
  }, dragRange);
  element.style.top = validPosition.y - startOffset + 'px';
  return element;
}

function removeDragElement(element) {
  document.body.removeChild(element);
}

function updateCurSorStyle(isOutOfRange) {
  if (isOutOfRange) {
    document.body.style.cursor = 'no-drop';
  } else {
    document.body.style.cursor = 'move';
  }
}

function removeCurSorStyle() {
  document.body.style.cursor = 'default';
}

function getDragRange(tableBody, _ref4) {
  var startOffset = _ref4.startOffset,
      rowHeight = _ref4.rowHeight;
  var tableBodyClientRect = tableBody.getBoundingClientRect();
  var height = tableBodyClientRect.height,
      width = tableBodyClientRect.width,
      x = tableBodyClientRect.x,
      y = tableBodyClientRect.y;
  return {
    minX: x,
    maxX: x + width,
    minY: y - rowHeight + startOffset,
    maxY: y + height + startOffset
  };
}

function getValidPosition(position, dragRange) {
  var x = position.x,
      y = position.y;
  var minX = dragRange.minX,
      maxX = dragRange.maxX,
      minY = dragRange.minY,
      maxY = dragRange.maxY;
  var newX = x < minX ? minX : x > maxX ? maxX : x;
  var newY = y < minY ? minY : y > maxY ? maxY : y;
  return {
    x: newX,
    y: newY
  };
}

function isOutOfDragRange(position, dragRange) {
  var x = position.x,
      y = position.y;
  var minX = dragRange.minX,
      maxX = dragRange.maxX,
      minY = dragRange.minY,
      maxY = dragRange.maxY;
  return x > maxX || x < minX || y > maxY || y < minY;
}