"use strict";

var __assign = void 0 && (void 0).__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];

      for (var p in s) {
        if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
      }
    }

    return t;
  };

  return __assign.apply(this, arguments);
};

var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  Object.defineProperty(o, k2, {
    enumerable: true,
    get: function get() {
      return m[k];
    }
  });
} : function (o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  o[k2] = m[k];
});

var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) {
  Object.defineProperty(o, "default", {
    enumerable: true,
    value: v
  });
} : function (o, v) {
  o["default"] = v;
});

var __importStar = void 0 && (void 0).__importStar || function (mod) {
  if (mod && mod.__esModule) return mod;
  var result = {};
  if (mod != null) for (var k in mod) {
    if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  }

  __setModuleDefault(result, mod);

  return result;
};

var __rest = void 0 && (void 0).__rest || function (s, e) {
  var t = {};

  for (var p in s) {
    if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  }

  if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
    if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  }
  return t;
};

var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
  return mod && mod.__esModule ? mod : {
    "default": mod
  };
};

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

var jsx_runtime_1 = require("react/jsx-runtime");

var React = __importStar(require("react"));

var react_1 = require("react");

var react_dom_1 = __importDefault(require("react-dom"));

var classnames_1 = __importDefault(require("classnames"));

var react_beautiful_dnd_1 = require("react-beautiful-dnd");

var react_virtualized_1 = require("react-virtualized");

var useStaticCallback_1 = __importDefault(require("../../hooks/useStaticCallback"));

var createScrollbar_1 = __importDefault(require("../scrollbar/createScrollbar"));

var icon_1 = __importDefault(require("../icon"));

require("./style/sort-list.css");

var useDataValue_1 = __importDefault(require("../../hooks/useDataValue"));

var field_item_1 = __importDefault(require("../field-item"));

var prefixCls = 'dmc-sort-list';
var itemCls = prefixCls + "-item";
var handleCls = itemCls + "-handle";
var labelCls = itemCls + "-label";
var ActionEnum;

(function (ActionEnum) {
  ActionEnum["Up"] = "up";
  ActionEnum["Down"] = "down";
  ActionEnum["Del"] = "del";
})(ActionEnum || (ActionEnum = {}));

var plainRowRenderer = function plainRowRenderer(index, value, item, handleClose) {
  return jsx_runtime_1.jsx("div", __assign({
    className: prefixCls + "-plain-row-wrap"
  }, {
    children: jsx_runtime_1.jsx(field_item_1["default"], {
      type: typeof item === 'string' ? 'text' : item.type || 'text',
      name: value,
      checked: true,
      onClose: handleClose,
      dataValue: ActionEnum.Del + "-" + index
    }, void 0)
  }), void 0);
};

var arrayMove = function arrayMove(list, startIndex, endIndex) {
  var result = Array.from(list);
  var removed = result.splice(startIndex, 1)[0];
  result.splice(endIndex, 0, removed);
  return result;
};

var SortList = function SortList(props) {
  var _a;

  var _b = props,
      type = _b.type,
      mode = _b.mode,
      listHeight = _b.listHeight,
      listWidth = _b.listWidth,
      rowHeight = _b.rowHeight,
      list = _b.list,
      defaultList = _b.defaultList,
      valueKey = _b.valueKey,
      labelKey = _b.labelKey,
      onChange = _b.onChange,
      renderItem = _b.renderItem,
      disabled = _b.disabled,
      visibleUpDown = _b.visibleUpDown,
      removable = _b.removable,
      useVirtual = _b.useVirtual,
      restProps = __rest(_b, ["type", "mode", "listHeight", "listWidth", "rowHeight", "list", "defaultList", "valueKey", "labelKey", "onChange", "renderItem", "disabled", "visibleUpDown", "removable", "useVirtual"]);

  var _c = React.useState(defaultList),
      unControlVal = _c[0],
      setUnControlVal = _c[1];

  var _d = React.useState(false),
      isDraging = _d[0],
      setDraging = _d[1];

  var isControl = ('list' in props);
  var val = isControl ? list : unControlVal;
  var isObj = typeof val[0] !== 'string';
  var psRef = React.useRef();
  var listRef = React.useRef(null);
  React.useEffect(function () {
    if (listRef.current) {
      var _a = createScrollbar_1["default"](listRef.current, type),
          ps = _a[0],
          destroy_1 = _a[1];

      psRef.current = ps;
      return function () {
        destroy_1();
        psRef.current = undefined;
      };
    }
  }, [type]);
  React.useEffect(function () {
    var _a;

    (_a = psRef.current) === null || _a === void 0 ? void 0 : _a.update();
  });
  var onDragEnd = useStaticCallback_1["default"](function (result) {
    if (!result.destination || result.destination.index === result.source.index) {
      return;
    }

    var list = arrayMove(val, result.source.index, result.destination.index);
    !isControl && setUnControlVal(list);
    setDraging(false);
    onChange && onChange(list, result);
  });
  var onDragStart = React.useCallback(function () {
    setDraging(true);
  }, []);
  var clickItemActionIcon = useDataValue_1["default"](function (value) {
    var _a = value.split('-'),
        action = _a[0],
        indexStr = _a[1];

    var cIndex = parseInt(indexStr);
    var list = [];

    if (action === ActionEnum.Up) {
      if (cIndex === 0) return;
      list = arrayMove(val, cIndex, 0);
    } else if (action === ActionEnum.Down) {
      if (cIndex === val.length - 1) return;
      list = arrayMove(val, cIndex, val.length - 1);
    } else if (action === ActionEnum.Del) {
      list = val.filter(function (_, index) {
        return index !== cIndex;
      });
    }

    !isControl && setUnControlVal(list);
    onChange && onChange(list);
  });
  var getRowRender = react_1.useCallback(function (_a) {
    var _b;

    var index = _a.index,
        style = _a.style;
    var item = val[index];
    var key = JSON.stringify(isObj ? item[valueKey] : item);
    var cls = classnames_1["default"](itemCls, (_b = {}, _b[itemCls + "-draging"] = isDraging, _b));
    return jsx_runtime_1.jsx(react_beautiful_dnd_1.Draggable, __assign({
      draggableId: key,
      index: index,
      isDragDisabled: disabled
    }, {
      children: function children(provided) {
        // combine virtual inline style and drag inline style
        var _a = provided.draggableProps,
            _b = _a.style,
            dragStyle = _b === void 0 ? {} : _b,
            otherDragProps = __rest(_a, ["style"]);

        var styleProps = {
          style: dragStyle
        };

        if (style) {
          styleProps.style = __assign(__assign({}, styleProps.style), style);
        }

        var val = isObj ? item[labelKey] : item;
        return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, {
          children: renderItem ? renderItem(provided, item, index, isDraging, styleProps.style) : jsx_runtime_1.jsxs("div", __assign({
            className: cls,
            ref: provided.innerRef
          }, otherDragProps, styleProps, {
            children: [!disabled && jsx_runtime_1.jsx(icon_1["default"], __assign({
              icon: "drag-handle",
              className: handleCls
            }, provided.dragHandleProps), void 0), mode === 'plain' ? plainRowRenderer(index, val, item, clickItemActionIcon) : jsx_runtime_1.jsx("div", __assign({
              className: labelCls
            }, {
              children: val
            }), void 0), mode === 'normal' && !!visibleUpDown && jsx_runtime_1.jsx(icon_1["default"], {
              icon: "vertical-align-top",
              className: itemCls + "-action",
              onClick: clickItemActionIcon,
              "data-value": ActionEnum.Up + "-" + index
            }, void 0), mode === 'normal' && !!visibleUpDown && jsx_runtime_1.jsx(icon_1["default"], {
              icon: "vertical-align-bottom",
              className: itemCls + "-action",
              onClick: clickItemActionIcon,
              "data-value": ActionEnum.Down + "-" + index
            }, void 0), mode === 'normal' && !!removable && jsx_runtime_1.jsx(icon_1["default"], {
              icon: "close",
              className: itemCls + "-action",
              onClick: clickItemActionIcon,
              "data-value": ActionEnum.Del + "-" + index
            }, void 0)]
          }), void 0)
        }, void 0);
      }
    }), key);
  }, [clickItemActionIcon, disabled, isDraging, isObj, labelKey, mode, removable, renderItem, val, valueKey, visibleUpDown]);
  var otherProps = react_1.useMemo(function () {
    if (useVirtual) {
      return {
        mode: 'virtual',
        renderClone: function renderClone(provided, snapshot, rubric) {
          var _a;

          var _index = rubric.source.index;
          var item = val[_index];
          var cls = classnames_1["default"](itemCls, (_a = {}, _a[itemCls + "-draging"] = snapshot.isDragging, _a));
          var content = isObj ? item[labelKey] : item;
          return jsx_runtime_1.jsx("div", __assign({}, provided.draggableProps, provided.dragHandleProps, {
            ref: provided.innerRef,
            className: cls
          }, {
            children: renderItem ? renderItem(provided, item, _index, snapshot.isDragging) : mode === 'plain' ? plainRowRenderer(_index, content, item) : jsx_runtime_1.jsx("div", __assign({
              className: labelCls
            }, {
              children: content
            }), void 0)
          }), void 0);
        }
      };
    } else {
      return {};
    }
  }, [isObj, labelKey, mode, renderItem, useVirtual, val]);
  return jsx_runtime_1.jsx("div", __assign({}, restProps, {
    className: classnames_1["default"](prefixCls, (_a = {}, _a[prefixCls + "-" + type] = type, _a[prefixCls + "-" + mode] = mode === 'plain', _a))
  }, {
    children: jsx_runtime_1.jsx(react_beautiful_dnd_1.DragDropContext, __assign({
      onDragEnd: onDragEnd,
      onDragStart: onDragStart
    }, {
      children: jsx_runtime_1.jsx(react_beautiful_dnd_1.Droppable, __assign({
        droppableId: prefixCls
      }, otherProps, {
        children: function children(provided) {
          return useVirtual ? jsx_runtime_1.jsx(react_virtualized_1.List, {
            height: listHeight || 300,
            width: listWidth || 200,
            rowCount: val.length,
            rowHeight: rowHeight,
            ref: function ref(_ref) {
              if (_ref) {
                // eslint-disable-next-line react/no-find-dom-node
                var dom = react_dom_1["default"].findDOMNode(_ref);

                if (dom instanceof HTMLElement) {
                  provided.innerRef(dom);
                  listRef.current = dom;
                }
              }
            },
            rowRenderer: getRowRender
          }, void 0) : jsx_runtime_1.jsxs("div", __assign({
            ref: provided.innerRef
          }, provided.droppableProps, {
            children: [val.map(function (_item, index) {
              return getRowRender({
                index: index
              });
            }), provided.placeholder]
          }), void 0);
        }
      }), void 0)
    }), void 0)
  }), void 0);
};

SortList.displayName = 'SortList';
var defaultProps = {
  mode: 'normal',
  rowHeight: 30,
  // list: [] as SortListItemType[],
  defaultList: [],
  valueKey: 'value',
  labelKey: 'label',
  disabled: false,
  useVirtual: false
};
SortList.defaultProps = defaultProps;
exports["default"] = SortList;
var SortListMemo = React.memo(SortList);
exports.SortListMemo = SortListMemo;
SortListMemo.displayName = 'SortListMemo';

