import { __assign, __extends, __rest } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import cx from 'classnames';
import { Component, createRef } from 'react';
import * as _sortableJS from 'sortablejs';
import reorder from '../utils/reorder';
import { EASE_OUT_CUBIC } from '../utils/timingFunctions';
var sortableJS = _sortableJS.default;
var DRAGGING_CLS = 'zent-sortable--grabbing';
var addElementsDraggingCursor = function (selector, element) {
    var container = element || document;
    container.querySelectorAll(selector).forEach(function (el) {
        el.style.cursor = 'grabbing';
    });
};
var removeElementsDraggingCursor = function (selector, element) {
    var container = element || document;
    container.querySelectorAll(selector).forEach(function (el) {
        el.style.cursor = '';
    });
};
var Sortable = (function (_super) {
    __extends(Sortable, _super);
    function Sortable() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.containerRef = createRef();
        _this.handleAddDraggingCursor = function () {
            var _a;
            var handle = _this.props.handle;
            addElementsDraggingCursor('html');
            handle && addElementsDraggingCursor(handle, _this.containerRef.current);
            (_a = _this.containerRef.current) === null || _a === void 0 ? void 0 : _a.classList.add(DRAGGING_CLS);
        };
        _this.handleRemoveDraggingCursor = function () {
            var _a;
            var handle = _this.props.handle;
            removeElementsDraggingCursor('html');
            handle && removeElementsDraggingCursor(handle, _this.containerRef.current);
            (_a = _this.containerRef.current) === null || _a === void 0 ? void 0 : _a.classList.remove(DRAGGING_CLS);
        };
        _this.initSortable = function () {
            var _a = _this.props, onMove = _a.onMove, onEnd = _a.onEnd, onChange = _a.onChange, filterClass = _a.filterClass, children = _a.children, rest = __rest(_a, ["onMove", "onEnd", "onChange", "filterClass", "children"]);
            var instance = _this.containerRef.current;
            if (!instance) {
                return;
            }
            var sortableOptions = __assign({ filter: filterClass ? "." + filterClass : '', ghostClass: 'zent-sortable__ghost', chosenClass: 'zent-sortable__chosen', dragClass: 'zent-sortable__drag', fallbackClass: 'zent-sortable__fallback', animation: 200, easing: EASE_OUT_CUBIC, forceFallback: true, onChoose: function (e) {
                    var _a, _b;
                    _this.handleAddDraggingCursor();
                    (_b = (_a = _this.props).onChoose) === null || _b === void 0 ? void 0 : _b.call(_a, e);
                }, onMove: function (e, originalEvent) {
                    var onMove = _this.props.onMove;
                    if (onMove) {
                        return onMove(e, originalEvent);
                    }
                    if (filterClass && e.related.classList.contains(filterClass)) {
                        return false;
                    }
                    return true;
                }, onUnchoose: function (e) {
                    var _a, _b;
                    _this.handleRemoveDraggingCursor();
                    (_b = (_a = _this.props).onUnchoose) === null || _b === void 0 ? void 0 : _b.call(_a, e);
                }, onEnd: function (e) {
                    var _a = _this.props, items = _a.items, onEnd = _a.onEnd, onChange = _a.onChange;
                    onEnd && onEnd(e);
                    if (!items) {
                        return;
                    }
                    var oldIndex = e.oldIndex, newIndex = e.newIndex;
                    var nextIndex = Math.max(0, Math.min(newIndex, items.length - 1));
                    var newItems = reorder(items, oldIndex, nextIndex);
                    onChange && onChange(newItems);
                } }, rest);
            _this.sortable = sortableJS.create(instance, sortableOptions);
        };
        return _this;
    }
    Sortable.prototype.destroySortableInstance = function () {
        if (this.sortable) {
            this.sortable.destroy();
            this.sortable = null;
        }
    };
    Sortable.prototype.componentDidMount = function () {
        this.initSortable();
    };
    Sortable.prototype.componentWillUnmount = function () {
        this.destroySortableInstance();
    };
    Sortable.prototype.render = function () {
        var _a = this.props, className = _a.className, children = _a.children, tag = _a.tag, handle = _a.handle;
        var classString = cx("zent-sortable", className, {
            'zent-sortable--handle': handle,
        });
        var Com = tag;
        return (_jsx(Com, __assign({ ref: this.containerRef, className: classString, "data-zv": "v10.0.11" }, { children: children }), void 0));
    };
    Sortable.defaultProps = {
        tag: 'div',
    };
    return Sortable;
}(Component));
export { Sortable };
export default Sortable;
