"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "Swipe", {
    enumerable: true,
    get: function() {
        return Swipe;
    }
});
var _interop_require_default = require("@swc/helpers/_/_interop_require_default");
var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
var _async_to_generator = require("@swc/helpers/_/_async_to_generator");
var _define_property = require("@swc/helpers/_/_define_property");
var _object_spread = require("@swc/helpers/_/_object_spread");
var _object_spread_props = require("@swc/helpers/_/_object_spread_props");
var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array");
var _ts_generator = require("@swc/helpers/_/_ts_generator");
var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames"));
var _components = require("@tarojs/components");
var _taro = require("@tarojs/taro");
var _usetouch = require("../../hooks/use-touch");
var _typings = require("../../utils/typings");
var _platform = require("../../utils/taro/platform");
var _userefstate = require("../../hooks/use-ref-state");
var _useuuid = require("../../hooks/use-uuid");
function preventDefault(event, isStopPropagation) {
    if (event.preventDefault && (typeof event.cancelable !== 'boolean' || event.cancelable)) {
        event.preventDefault();
    }
    if (isStopPropagation && event.stopPropagation) {
        event.stopPropagation();
    }
}
var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), {
    name: ''
});
var Swipe = /*#__PURE__*/ (0, _react.forwardRef)(function(props, instanceRef) {
    var classPrefix = 'nut-swipe';
    var touch = (0, _usetouch.useTouch)();
    var uid = (0, _useuuid.useUuid)();
    var leftId = "swipe-left-".concat(uid);
    var rightId = "swipe-right-".concat(uid);
    var _$_object_spread = (0, _object_spread._)({}, defaultProps, props), children = _$_object_spread.children, className = _$_object_spread.className, style = _$_object_spread.style;
    var root = (0, _react.useRef)();
    var opened = (0, _react.useRef)(false);
    var lockClick = (0, _react.useRef)(false);
    var startOffset = (0, _react.useRef)(0);
    var leftWrapper = (0, _react.useRef)(null);
    var rightWrapper = (0, _react.useRef)(null);
    var _useState = (0, _sliced_to_array._)((0, _react.useState)({
        offset: 0,
        dragging: false
    }), 2), state = _useState[0], setState = _useState[1];
    var _useRefState = (0, _sliced_to_array._)((0, _userefstate.useRefState)({
        left: 0,
        right: 0
    }), 2), actionWidth = _useRefState[0], updateState = _useRefState[1];
    var setActionWidth = (0, _react.useCallback)(function(side, width) {
        if (actionWidth.current[side] === width) return;
        updateState((0, _object_spread_props._)((0, _object_spread._)({}, actionWidth.current), (0, _define_property._)({}, side, width)));
    }, [
        actionWidth,
        updateState
    ]);
    var getActionRect = function getActionRect(element, id) {
        return new Promise(function(resolve) {
            if (!element) {
                resolve(null);
                return;
            }
            var query = (0, _taro.createSelectorQuery)();
            var scope = element === null || element === void 0 ? void 0 : element._scope;
            var scopedQuery = scope ? query.in(scope) : query;
            scopedQuery.select("#".concat(id)).boundingClientRect().exec(function() {
                var rect = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
                resolve(rect[0] || null);
            });
        });
    };
    var getWidth = (0, _react.useCallback)(function() {
        return (0, _async_to_generator._)(function() {
            var leftRect, rightRect;
            return (0, _ts_generator._)(this, function(_state) {
                switch(_state.label){
                    case 0:
                        if (!props.leftAction) return [
                            3,
                            2
                        ];
                        return [
                            4,
                            getActionRect(leftWrapper.current, leftId)
                        ];
                    case 1:
                        leftRect = _state.sent();
                        leftRect && setActionWidth('left', leftRect.width);
                        _state.label = 2;
                    case 2:
                        if (!props.rightAction) return [
                            3,
                            4
                        ];
                        return [
                            4,
                            getActionRect(rightWrapper.current, rightId)
                        ];
                    case 3:
                        rightRect = _state.sent();
                        rightRect && setActionWidth('right', rightRect.width);
                        _state.label = 4;
                    case 4:
                        return [
                            2
                        ];
                }
            });
        })();
    }, [
        leftId,
        props.leftAction,
        props.rightAction,
        rightId,
        setActionWidth
    ]);
    var getWidthRef = (0, _react.useRef)(getWidth);
    (0, _react.useEffect)(function() {
        getWidthRef.current = getWidth;
    }, [
        getWidth
    ]);
    // 页面 ready 后测量操作区域宽度，宽度未变化时不触发更新。
    (0, _taro.useReady)(function() {
        (0, _taro.nextTick)(function() {
            getWidthRef.current();
        });
    });
    var wrapperStyle = {
        transform: "translate(".concat(state.offset).concat(!(0, _platform.harmony)() ? 'px' : '', ", 0)"),
        transitionDuration: state.dragging ? '0s' : '.6s'
    };
    var onTouchStart = function onTouchStart(event) {
        return (0, _async_to_generator._)(function() {
            var _props_onTouchStart;
            return (0, _ts_generator._)(this, function(_state) {
                if (!props.disabled) {
                    ;
                    getWidth();
                    startOffset.current = state.offset;
                    touch.start(event);
                    (_props_onTouchStart = props.onTouchStart) === null || _props_onTouchStart === void 0 ? void 0 : _props_onTouchStart.call(props, event);
                }
                return [
                    2
                ];
            });
        })();
    };
    var onTouchMove = function onTouchMove(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 = (0, _object_spread_props._)((0, _object_spread._)({}, state), {
                dragging: true
            });
            var isEdge = !opened.current || touch.deltaX.current * startOffset.current < 0;
            if (isEdge) {
                preventDefault(event, true);
            }
            newState.offset = rangeCalculation(touch.deltaX.current + startOffset.current, -actionWidth.current.right || 0, actionWidth.current.left || 0);
            setState(newState);
        }
    };
    var onTouchEnd = function onTouchEnd(event) {
        if (state.dragging) {
            var _props_onTouchEnd;
            setState(function(v) {
                return (0, _object_spread_props._)((0, _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 toggle(side) {
        var offset = Math.abs(state.offset);
        var base = 0.3;
        var baseNum = opened.current ? 1 - base : base;
        var width = side === 'left' ? actionWidth.current.left : actionWidth.current.right;
        if (width && offset > Number(width) * baseNum) {
            open(side);
        } else {
            close(side);
        }
    };
    var open = function open(side) {
        var _props_onOpen;
        opened.current = true;
        var offset = side === 'left' ? actionWidth.current.left : -actionWidth.current.right;
        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 (0, _object_spread_props._)((0, _object_spread._)({}, v), {
                offset: Number(offset) || 0
            });
        });
    };
    var close = function close(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 (0, _object_spread_props._)((0, _object_spread._)({}, v), {
                offset: 0
            });
        });
    };
    var rangeCalculation = function rangeCalculation(num, min, max) {
        return Math.min(Math.max(Number(num), Number(min)), Number(max));
    };
    var renderActionContent = function renderActionContent(side) {
        if (props["".concat(side, "Action")]) {
            return /*#__PURE__*/ _react.default.createElement(_components.View, {
                ref: side === 'left' ? leftWrapper : rightWrapper,
                className: "".concat(classPrefix, "-").concat(side),
                id: side === 'left' ? leftId : rightId,
                onClick: function onClick(e) {
                    return handleOperate(e, side);
                }
            }, props["".concat(side, "Action")]);
        }
        return null;
    };
    var handleOperate = function handleOperate(event, position) {
        event.stopPropagation();
        if (props.beforeClose) {
            props.beforeClose(position);
        } else {
            var _props_onActionClick;
            (_props_onActionClick = props.onActionClick) === null || _props_onActionClick === void 0 ? void 0 : _props_onActionClick.call(props, event, position);
        }
    };
    (0, _react.useImperativeHandle)(instanceRef, function() {
        return {
            open: open,
            close: function close1() {
                return close();
            }
        };
    });
    (0, _react.useEffect)(function() {
        if ((0, _platform.harmony)()) return;
        var handler = function handler(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.default.createElement(_components.View, {
        ref: root,
        className: (0, _classnames.default)(classPrefix, className),
        onTouchStart: function onTouchStart1(e) {
            return onTouchStart(e);
        },
        onTouchMove: function onTouchMove1(e) {
            return onTouchMove(e);
        },
        onTouchEnd: function onTouchEnd1(e) {
            return onTouchEnd(e);
        },
        style: style
    }, /*#__PURE__*/ _react.default.createElement(_components.View, {
        className: "".concat(classPrefix, "-wrapper"),
        style: wrapperStyle
    }, renderActionContent('left'), children, renderActionContent('right')));
});
Swipe.displayName = 'NutSwipe';
