"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports["default"] = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _react = _interopRequireDefault(require("react"));
var _utils = require("./utils");
var _DragLayer = _interopRequireDefault(require("./DragLayer"));
var _Container = _interopRequireDefault(require("./Container"));
var _AutoScroller = _interopRequireDefault(require("./AutoScroller"));
var _NestableListBaseContext = require("./NestableListBaseContext");
var _withDNDContext = _interopRequireDefault(require("./withDNDContext"));
var _ZIndex = require("../common/ZIndex");
var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/NestableListBase/NestableListBase.jsx";
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2["default"])(o), (0, _possibleConstructorReturn2["default"])(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2["default"])(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function replaceNegativeIndex(items, nextPosition, childrenProperty) {
  var currItems = items;
  return nextPosition.map(function (nextIndex) {
    if (nextIndex !== -1) {
      currItems = currItems[nextIndex][childrenProperty] || [];
      return nextIndex;
    }
    return currItems.length;
  });
}

// fixing a bug where the new path is increased in nesting
// and the first position jumps too far by 2, and that's why it decreased by 1
// need to check if the jump can become more severe
function getRealNextPosition(prev, next) {
  // moving up a level
  if (prev.length < next.length) {
    return next.map(function (nextIndex, i) {
      if (typeof prev[i] !== 'number') {
        return nextIndex;
      }
      return nextIndex > prev[i] ? nextIndex - 1 : nextIndex;
    });
  }
  return next;
}
var NestableListBase = /*#__PURE__*/function (_React$PureComponent) {
  function NestableListBase() {
    var _this;
    (0, _classCallCheck2["default"])(this, NestableListBase);
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _callSuper(this, NestableListBase, [].concat(args));
    _this.state = {
      items: _this.props.items,
      dragging: false
    };
    _this.containerRef = /*#__PURE__*/_react["default"].createRef();
    // drag and drop between multiple nestable lists is not supported
    // according to prevent it for now was created groupName - unique value for every nestable list
    // somethings similar exists in SortableListBase component.
    _this.groupName = (0, _utils.generateUniqueGroupId)();
    // FIXME: reference to latest `state.items`. This is a workaround for issue
    // with `moveItem` where it updates `state.items` and if the update occurs
    // multiple times before the component re-renders, the `state.items` will be
    // be updated based on the previous state, not the latest one, which in some
    // cases leads to item duplication or removal.
    // This should be solved by not referring to current state by `this.state` and
    // instead providing callback to `setState` that receives the latest state.
    // However, due to architectural decisions this is not possible without
    // rewriting the whole component as `moveItem` must return new position of the
    // dragged item which is then used by the item itself to update its state.
    _this._items = _this.props.items;
    _this.moveItem = function (_ref) {
      var dragItem = _ref.dragItem,
        prevPosition = _ref.prevPosition,
        nextPosition = _ref.nextPosition;
      var _this$props = _this.props,
        childrenProperty = _this$props.childrenProperty,
        preventChangeDepth = _this$props.preventChangeDepth,
        preventChangeParent = _this$props.preventChangeParent,
        enforcePinnedOrder = _this$props.enforcePinnedOrder,
        items = _this$props.items;
      if (dragItem.preventItemChangeDepth && nextPosition.length !== prevPosition.length) {
        return prevPosition;
      }
      if (preventChangeDepth && nextPosition.length > 1) {
        var parent = (0, _utils.getDropParent)(items, nextPosition, childrenProperty);
        if (!parent) {
          return prevPosition;
        }
      }
      if (preventChangeParent) {
        var prevParentPath = prevPosition.slice(0, -1);
        var nextParentPath = nextPosition.slice(0, -1);
        var prevParent = (0, _utils.getDropParent)(items, prevParentPath, childrenProperty);
        var nextParent = (0, _utils.getDropParent)(items, nextParentPath, childrenProperty);
        if ((prevParent == null ? void 0 : prevParent.id) !== (nextParent == null ? void 0 : nextParent.id)) {
          return prevPosition;
        }
      }
      var newItems = _this._items;

      // the remove action might affect the next position,
      // so update next coordinates accordingly
      var realNextPosition = getRealNextPosition(prevPosition, nextPosition);
      if (enforcePinnedOrder) {
        var shouldProhibitPinMoveDown = !!dragItem.isPinned && !realNextPosition.isPinned;
        var shouldProhibitNonPinMoveUp = !dragItem.isPinned && !!realNextPosition.isPinned;
        if (shouldProhibitPinMoveDown && shouldProhibitNonPinMoveUp) {
          return prevPosition;
        }
      }
      if (realNextPosition[realNextPosition.length - 1] === -1) {
        realNextPosition = replaceNegativeIndex(newItems, realNextPosition, childrenProperty);
      }
      newItems = (0, _utils.removeFromTree)(newItems, prevPosition, childrenProperty);
      newItems = (0, _utils.addToTree)(newItems, dragItem, realNextPosition, childrenProperty);
      _this._items = newItems;
      _this.setState({
        items: newItems
      });
      return realNextPosition;
    };
    _this.dropItem = function (item) {
      _this.props.onUpdate == null || _this.props.onUpdate({
        items: _this.state.items,
        item: item
      });
    };
    _this.onDragStart = function (itemProps) {
      _this.setState({
        dragging: true
      });
      _this.props.onDragStart == null || _this.props.onDragStart(itemProps);
    };
    _this.onDragEnd = function (itemProps) {
      _this.setState({
        dragging: false
      });
      _this.props.onDragEnd == null || _this.props.onDragEnd(itemProps);
    };
    return _this;
  }
  (0, _inherits2["default"])(NestableListBase, _React$PureComponent);
  return (0, _createClass2["default"])(NestableListBase, [{
    key: "UNSAFE_componentWillReceiveProps",
    value:
    // tried to use getDerivedStateFromProps but encounter an issue where the state was
    // updated internally but props items stayed the same and it caused the new state to be
    // overridden with the old state
    // can be done if component is controlled but requires refactor
    function UNSAFE_componentWillReceiveProps(newProps) {
      if (newProps.items !== this.state.items && !this.state.dragging) {
        this.setState({
          items: newProps.items
        });
        this._items = newProps.items;
      }
    }
  }, {
    key: "render",
    value: function render() {
      var items = this.state.items;
      var _this$props2 = this.props,
        renderItem = _this$props2.renderItem,
        readOnly = _this$props2.readOnly,
        childrenProperty = _this$props2.childrenProperty,
        childrenStyle = _this$props2.childrenStyle,
        renderAction = _this$props2.renderAction,
        isRenderDraggingChildren = _this$props2.isRenderDraggingChildren,
        useDragHandle = _this$props2.useDragHandle,
        maxDepth = _this$props2.maxDepth,
        preventChangeDepth = _this$props2.preventChangeDepth,
        preventChangeParent = _this$props2.preventChangeParent,
        enforcePinnedOrder = _this$props2.enforcePinnedOrder,
        threshold = _this$props2.threshold,
        theme = _this$props2.theme,
        renderPrefix = _this$props2.renderPrefix,
        dragLayerZIndex = _this$props2.dragLayerZIndex,
        zIndex = _this$props2.zIndex;
      return /*#__PURE__*/_react["default"].createElement(_NestableListBaseContext.NestableListBaseContext.Provider, {
        value: {
          groupName: this.groupName,
          useDragHandle: useDragHandle,
          maxDepth: maxDepth,
          preventChangeDepth: preventChangeDepth,
          preventChangeParent: preventChangeParent,
          enforcePinnedOrder: enforcePinnedOrder,
          threshold: threshold,
          readOnly: readOnly,
          renderItem: renderItem,
          renderPrefix: renderPrefix,
          moveItem: this.moveItem,
          dropItem: this.dropItem,
          onDragStart: this.onDragStart,
          onDragEnd: this.onDragEnd
        },
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 210,
          columnNumber: 7
        }
      }, /*#__PURE__*/_react["default"].createElement("div", {
        ref: this.containerRef,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 228,
          columnNumber: 9
        }
      }, /*#__PURE__*/_react["default"].createElement(_Container["default"], {
        treeDepth: 1,
        items: items,
        renderAction: renderAction,
        parentPosition: [],
        childrenProperty: childrenProperty,
        childrenStyle: childrenStyle,
        isRenderDraggingChildren: isRenderDraggingChildren,
        topLevel: true,
        theme: theme,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 229,
          columnNumber: 11
        }
      }), this.state.dragging && /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, {
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 241,
          columnNumber: 13
        }
      }, /*#__PURE__*/_react["default"].createElement(_DragLayer["default"], {
        siblings: items,
        isRenderDraggingChildren: isRenderDraggingChildren,
        renderItem: renderItem,
        childrenProperty: childrenProperty,
        childrenStyle: childrenStyle,
        theme: theme,
        dragLayerZIndex: zIndex !== null && zIndex !== void 0 ? zIndex : dragLayerZIndex,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 242,
          columnNumber: 15
        }
      }), /*#__PURE__*/_react["default"].createElement(_AutoScroller["default"], {
        containerRef: this.containerRef,
        __self: this,
        __source: {
          fileName: _jsxFileName,
          lineNumber: 251,
          columnNumber: 15
        }
      }))));
    }
  }]);
}(_react["default"].PureComponent);
NestableListBase.displayName = 'NestableListBase';
NestableListBase.defaultProps = {
  items: [],
  isRenderDraggingChildren: false,
  childrenProperty: 'children',
  childrenStyle: {},
  renderPrefix: function renderPrefix() {
    return null;
  },
  renderAction: function renderAction() {
    return null;
  },
  onUpdate: function onUpdate() {},
  useDragHandle: false,
  preventChangeDepth: false,
  preventChangeParent: false,
  enforcePinnedOrder: false,
  maxDepth: Infinity,
  threshold: 30,
  dragLayerZIndex: _ZIndex.ZIndex.nestableListDragLayer
};
var _default = exports["default"] = (0, _withDNDContext["default"])(NestableListBase);