import React from 'react';
import shallowEqual from 'shallowequal';
import DraggableSource from './components/DraggableSource';
import DraggableTarget from './components/DraggableTarget';
import DraggableManager from './components/DraggableManager';
export class Draggable extends React.Component {
    constructor() {
        super(...arguments);
        this.state = {
            delayed: false,
        };
        this.delayTimer = null;
        this.resetDelayState = () => {
            if (!!this.props.delay) {
                this.setState({ delayed: false });
                this.resetDelayTimer();
            }
        };
        this.resetDelayTimer = () => {
            clearTimeout(this.delayTimer);
            this.delayTimer = null;
        };
        this.countDelay = () => {
            if (!!this.props.delay) {
                this.setState({ delayed: true });
                this.resetDelayTimer();
                this.delayTimer = setTimeout(() => this.setState({ delayed: false }), this.props.delay);
            }
        };
        this.onDragStart = ({ id, index, containerId, groupName, item }) => {
            if (this.props.onDragStart) {
                this.props.onDragStart({ id, index, containerId, groupName, item });
            }
            this.resetDelayTimer();
        };
        this.onDragEnd = ({ id, index, containerId, groupName, item }) => {
            if (this.props.onDragEnd) {
                this.props.onDragEnd({ id, index, containerId, groupName, item });
            }
            this.resetDelayState();
        };
        this.canDrag = ({ id, index, containerId, groupName, item }) => {
            const canDragByDelay = !!this.props.delay ? !this.state.delayed : true;
            const propsCanDrag = this.props.canDrag
                ? this.props.canDrag({
                    id,
                    index,
                    containerId,
                    groupName,
                    item,
                })
                : true;
            if (!canDragByDelay) {
                this.resetDelayState();
            }
            return canDragByDelay && propsCanDrag;
        };
    }
    shouldComponentUpdate({ listOfPropsThatAffectItems, ...nextProps }, nextState) {
        const { listOfPropsThatAffectItems: prevListOfPropsThatAffectItems, ...prevProps } = this.props;
        if (!shallowEqual(nextProps, prevProps) ||
            !shallowEqual(listOfPropsThatAffectItems, prevListOfPropsThatAffectItems)) {
            return true;
        }
        if (!shallowEqual(nextState, this.state)) {
            return true;
        }
        return false;
    }
    componentWillUnmount() {
        this.resetDelayTimer();
    }
    render() {
        const { hasDragged, ...restProps } = this.props;
        return (React.createElement(DraggableTarget, { ...restProps },
            React.createElement("div", { onMouseDown: this.countDelay, onMouseUp: this.resetDelayState, "data-hook": "delay-wrapper" },
                React.createElement(DraggableSource, { ...restProps, ignoreMouseEvents: hasDragged, onDragStart: this.onDragStart, onDragEnd: this.onDragEnd, canDrag: this.canDrag, delayed: !!this.props.delay && this.state.delayed }))));
    }
}
Draggable.defaultProps = {
    droppable: true,
};
Draggable.Item = Draggable;
Draggable.Manager = DraggableManager;
export default Draggable;
//# sourceMappingURL=Draggable.js.map