import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useRef, forwardRef, useState, useCallback, useImperativeHandle, useEffect } from "react";
import classNames from "classnames";
import { useTouch } from "../../hooks/use-touch";
import { getRect } from "../../hooks/use-client-rect";
function preventDefault(event, isStopPropagation) {
    if (typeof event.cancelable !== 'boolean' || event.cancelable) {
        event.preventDefault();
    }
    if (isStopPropagation) {
        event.stopPropagation();
    }
}
var defaultProps = {
    name: ''
};
export var Swipe = /*#__PURE__*/ forwardRef(function(props, instanceRef) {
    var classPrefix = 'nut-swipe';
    var touch = useTouch();
    var _$_object_spread = _object_spread({}, defaultProps, props), children = _$_object_spread.children, className = _$_object_spread.className, style = _$_object_spread.style;
    var root = useRef();
    var opened = useRef(false);
    var lockClick = useRef(false);
    var startOffset = useRef(0);
    var _useState = _sliced_to_array(useState({
        offset: 0,
        dragging: false
    }), 2), state = _useState[0], setState = _useState[1];
    var _useState1 = _sliced_to_array(useState({
        left: 0,
        right: 0
    }), 2), actionWidth = _useState1[0], setActionWidth = _useState1[1];
    var wrapperStyle = {
        transform: "translate3d(".concat(state.offset, "px, 0, 0)"),
        transitionDuration: state.dragging ? '0s' : '.6s'
    };
    var leftWidth = actionWidth.left;
    var rightWidth = actionWidth.right;
    var onTouchStart = function(event) {
        if (!props.disabled) {
            var _props_onTouchStart;
            startOffset.current = state.offset;
            touch.start(event);
            (_props_onTouchStart = props.onTouchStart) === null || _props_onTouchStart === void 0 ? void 0 : _props_onTouchStart.call(props, event);
        }
    };
    var onTouchMove = function(event) {
        var _props_onTouchMove;
        if (props.disabled) {
            return;
        }
        touch.move(event);
        (_props_onTouchMove = props.onTouchMove) === null || _props_onTouchMove === void 0 ? void 0 : _props_onTouchMove.call(props, event);
        if (touch.isHorizontal()) {
            lockClick.current = true;
            var newState = _object_spread_props(_object_spread({}, state), {
                dragging: true
            });
            var isEdge = !opened || touch.deltaX.current * startOffset.current < 0;
            if (isEdge) {
                preventDefault(event, true);
            }
            newState.offset = rangeCalculation(touch.deltaX.current + startOffset.current, -rightWidth, leftWidth);
            setState(newState);
        }
    };
    var onTouchEnd = function(event) {
        if (state.dragging) {
            var _props_onTouchEnd;
            setState(function(v) {
                return _object_spread_props(_object_spread({}, v), {
                    dragging: false
                });
            });
            toggle(state.offset > 0 ? 'left' : 'right');
            setTimeout(function() {
                lockClick.current = false;
            }, 0);
            (_props_onTouchEnd = props.onTouchEnd) === null || _props_onTouchEnd === void 0 ? void 0 : _props_onTouchEnd.call(props, event);
        }
    };
    var toggle = function(side) {
        var offset = Math.abs(state.offset);
        var base = 0.3;
        var baseNum = opened ? 1 - base : base;
        var width = side === 'left' ? leftWidth : rightWidth;
        if (width && offset > Number(width) * baseNum) {
            open(side);
        } else {
            close(side);
        }
    };
    var open = function(side) {
        var _props_onOpen;
        opened.current = true;
        var offset = side === 'left' ? leftWidth : -rightWidth;
        var name = props.name;
        (_props_onOpen = props.onOpen) === null || _props_onOpen === void 0 ? void 0 : _props_onOpen.call(props, {
            name: name,
            position: side
        });
        setState(function(v) {
            return _object_spread_props(_object_spread({}, v), {
                offset: Number(offset) || 0
            });
        });
    };
    var close = function(position) {
        if (opened.current) {
            var _props_onClose;
            opened.current = false;
            (_props_onClose = props.onClose) === null || _props_onClose === void 0 ? void 0 : _props_onClose.call(props, {
                name: props.name,
                position: position || 'left'
            });
        }
        setState(function(v) {
            return _object_spread_props(_object_spread({}, v), {
                offset: 0
            });
        });
    };
    var rangeCalculation = function(num, min, max) {
        return Math.min(Math.max(Number(num), Number(min)), Number(max));
    };
    var getNodeWidth = function(node) {
        if (node) {
            var ele = getRect(node);
            return ele.width;
        }
        return 0;
    };
    var leftRef = useCallback(function(node) {
        if (node !== null) {
            setActionWidth(function(v) {
                return _object_spread_props(_object_spread({}, v), {
                    left: getNodeWidth(node)
                });
            });
        }
    }, [
        props.leftAction
    ]);
    var rightRef = useCallback(function(node) {
        if (node !== null) {
            setActionWidth(function(v) {
                return _object_spread_props(_object_spread({}, v), {
                    right: getNodeWidth(node)
                });
            });
        }
    }, [
        props.rightAction
    ]);
    var renderActionContent = function(side, measuredRef) {
        if (props["".concat(side, "Action")]) {
            return /*#__PURE__*/ React.createElement("div", {
                ref: measuredRef,
                className: "".concat(classPrefix, "-").concat(side),
                onClick: function(e) {
                    return handleOperate(e, side);
                }
            }, props["".concat(side, "Action")]);
        }
        return null;
    };
    var handleOperate = function(event, position) {
        event.stopPropagation();
        if (props.beforeClose) {
            props.beforeClose(position);
        } else {
            props.onActionClick && props.onActionClick(event, position);
        }
    };
    useImperativeHandle(instanceRef, function() {
        return {
            open: open,
            close: function() {
                return close();
            }
        };
    });
    useEffect(function() {
        var handler = function(event) {
            var targets = [
                root
            ];
            if (targets.some(function(targetItem) {
                var targetElement = targetItem.current || targetItem;
                return !targetElement || (targetElement === null || targetElement === void 0 ? void 0 : targetElement.contains(event.target));
            })) {
                return;
            }
            close();
        };
        document.addEventListener('touchstart', handler);
        return function() {
            document.removeEventListener('touchstart', handler);
        };
    }, []);
    return /*#__PURE__*/ React.createElement("div", {
        ref: root,
        className: classNames(classPrefix, className),
        onTouchStart: function(e) {
            return onTouchStart(e);
        },
        onTouchMove: function(e) {
            return onTouchMove(e);
        },
        onTouchEnd: function(e) {
            return onTouchEnd(e);
        },
        style: style
    }, /*#__PURE__*/ React.createElement("div", {
        className: "".concat(classPrefix, "-wrapper"),
        style: wrapperStyle
    }, renderActionContent('left', leftRef), children, renderActionContent('right', rightRef)));
});
Swipe.displayName = 'NutSwipe';
