"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "Swiper", {
    enumerable: true,
    get: function() {
        return Swiper;
    }
});
var _interop_require_default = require("@swc/helpers/_/_interop_require_default");
var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
var _define_property = require("@swc/helpers/_/_define_property");
var _object_spread = require("@swc/helpers/_/_object_spread");
var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array");
var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
var _react1 = require("@use-gesture/react");
var _web = require("@react-spring/web");
var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames"));
var _indicator = /*#__PURE__*/ _interop_require_default._(require("../indicator"));
var _userefstate = require("../../hooks/use-ref-state");
var _default = require("./effects/default");
var _focus = require("./effects/focus");
var defaultProps = {
    direction: 'horizontal',
    indicator: false,
    loop: false,
    duration: 3000,
    autoPlay: false,
    defaultValue: 0,
    touchable: true,
    effect: undefined
};
var Swiper = /*#__PURE__*/ _react.default.forwardRef(function(props, ref) {
    var boundIndex = function boundIndex(current) {
        var min = 0;
        var max = count - 1;
        if (current === max && !loop && props.slideSize) {
            var slideSize = props.slideSize;
            var swiperSize = getSwiperSize();
            var ratio = (swiperSize - slideSize) / slideSize;
            return bound(current, min, max - ratio);
        }
        return current;
    };
    var classPrefix = 'nut-swiper';
    var _$_object_spread = (0, _object_spread._)({}, defaultProps, props), children = _$_object_spread.children, direction = _$_object_spread.direction, indicator = _$_object_spread.indicator, loop = _$_object_spread.loop, effect = _$_object_spread.effect, autoPlay = _$_object_spread.autoPlay, touchable = _$_object_spread.touchable, defaultValue = _$_object_spread.defaultValue, duration = _$_object_spread.duration, style = _$_object_spread.style, className = _$_object_spread.className;
    var isVertical = direction === 'vertical';
    var count = (0, _react.useMemo)(function() {
        var c = 0;
        _react.default.Children.map(children, function(child, index) {
            c += 1;
        });
        return c;
    }, [
        children
    ]);
    var getSlideSize = function getSlideSize() {
        if (props.slideSize) return props.slideSize;
        if (stageRef.current) {
            if (isVertical) return stageRef.current.offsetHeight;
            return stageRef.current.offsetWidth;
        }
        return 0;
    };
    var getSwiperSize = function getSwiperSize() {
        if (swiperRef.current) {
            if (isVertical) return swiperRef.current.offsetHeight;
            return swiperRef.current.offsetWidth;
        }
        return 0;
    };
    var bound = function bound(v, min, max) {
        if (min !== undefined) {
            v = Math.max(v, min);
        }
        if (max !== undefined) {
            v = Math.min(v, max);
        }
        return v;
    };
    var timeoutRef = (0, _react.useRef)(null);
    var _useState = (0, _sliced_to_array._)((0, _react.useState)(false), 2), dragging = _useState[0], setDragging = _useState[1];
    var _useRefState = (0, _sliced_to_array._)((0, _userefstate.useRefState)(defaultValue), 2), current = _useRefState[0], setCurrent = _useRefState[1];
    var stageRef = (0, _react.useRef)(null);
    var swiperRef = (0, _react.useRef)(null);
    var _useSpring = (0, _sliced_to_array._)((0, _web.useSpring)(function() {
        return {
            x: !isVertical ? current.current * 100 * -1 : 0,
            y: isVertical ? current.current * 100 * -1 : 0,
            s: 0,
            reset: function reset() {},
            config: {
                tension: 200,
                friction: 30
            }
        };
    }), 2), springs = _useSpring[0], api = _useSpring[1];
    (0, _react.useEffect)(function() {
        var _obj;
        api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', boundIndex(current.current) * -1 * 100), (0, _define_property._)(_obj, "immediate", true), _obj));
    }, [
        swiperRef.current
    ]);
    var swiperDirection = (0, _react.useRef)(1);
    var _useList = (0, _sliced_to_array._)((0, _focus.useList)(effect, count, current), 2), transforms = _useList[0], setTransforms = _useList[1];
    // 自动播放
    var runTimeSwiper = function runTimeSwiper1() {
        var durationNumber = typeof duration === 'string' ? parseInt(duration) : duration;
        var d = typeof autoPlay === 'number' ? autoPlay : durationNumber;
        timeoutRef.current = window.setTimeout(function() {
            next();
            runTimeSwiper();
        }, d);
    };
    (0, _react.useEffect)(function() {
        if (!autoPlay || dragging) return;
        runTimeSwiper();
        return function() {
            if (timeoutRef.current) window.clearTimeout(timeoutRef.current);
        };
    }, [
        autoPlay,
        duration,
        dragging,
        count
    ]);
    var to = function to(index) {
        var immediate = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
        var _props_onChange;
        var targetIndex = bound(index, 0, count - 1);
        if (loop) {
            var cycleIndex = index % count;
            targetIndex = cycleIndex < 0 ? cycleIndex + count : cycleIndex;
        }
        setCurrent(targetIndex);
        (_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, targetIndex);
        if (effect) {
            (0, _focus.updateTransform)(transforms, setTransforms, effect, targetIndex);
        }
        var _obj;
        api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', (loop ? -index : boundIndex(targetIndex) * -1) * 100), (0, _define_property._)(_obj, "s", 0), (0, _define_property._)(_obj, "immediate", immediate), _obj));
    };
    var getSpringsAxis = function getSpringsAxis() {
        return springs[isVertical ? 'y' : 'x'];
    };
    var next = function next() {
        to(Math.round(-getSpringsAxis().get() / 100) + 1);
    };
    var prev = function prev() {
        to(Math.round(-getSpringsAxis().get() / 100) - 1);
    };
    _react.default.useImperativeHandle(ref, function() {
        return {
            to: to,
            next: next,
            prev: prev
        };
    });
    var bind = (0, _react1.useDrag)(function(state) {
        var axis = Number(isVertical);
        var slideSize = getSlideSize();
        var offset = state.offset[axis];
        setDragging(!!state.dragging);
        var distance = state.distance[axis];
        swiperDirection.current = state.direction[axis];
        if (state.last) {
            // 计算位置
            var swipeDirection = state.direction[axis];
            var velocity = state.velocity[axis];
            var minIndex = Math.floor(offset / slideSize);
            var maxIndex = minIndex + 1;
            var index = Math.round((offset + velocity * 2000 * swipeDirection) / slideSize);
            to(bound(index, minIndex, maxIndex));
        } else {
            var _obj;
            // 实时移动，换算百分比
            api.start((_obj = {}, (0, _define_property._)(_obj, isVertical ? 'y' : 'x', -(offset / slideSize * 100)), (0, _define_property._)(_obj, "s", distance / slideSize), (0, _define_property._)(_obj, "immediate", true), _obj));
        }
    }, {
        enabled: touchable,
        transform: function transform(param) {
            var _param = (0, _sliced_to_array._)(param, 2), x = _param[0], y = _param[1];
            return [
                -x,
                -y
            ];
        },
        from: function from() {
            // 由百分比转换到像素
            var slideSize = getSlideSize();
            var x = springs.x.get() / 100 * slideSize;
            var y = springs.y.get() / 100 * slideSize;
            return [
                -x,
                -y
            ];
        },
        triggerAllEvents: true,
        bounds: function bounds() {
            if (loop) return {};
            var slideSize = getSlideSize();
            var swiperSize = getSwiperSize();
            if (isVertical) {
                return {
                    top: 0,
                    bottom: (count - 1) * slideSize
                };
            }
            return {
                left: 0,
                right: (count - 1) * slideSize
            };
        },
        preventDefault: true,
        rubberband: true,
        axis: isVertical ? 'y' : 'x',
        pointer: {
            touch: true
        }
    });
    var renderIndicator = function renderIndicator() {
        if (/*#__PURE__*/ _react.default.isValidElement(indicator)) return indicator;
        if (!indicator) return null;
        var _obj;
        return /*#__PURE__*/ _react.default.createElement("div", {
            className: (0, _classnames.default)((_obj = {}, (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator"), true), (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator-vertical"), isVertical), (0, _define_property._)(_obj, "".concat(classPrefix, "-indicator-horizontal"), !isVertical), _obj))
        }, /*#__PURE__*/ _react.default.createElement(_indicator.default, {
            current: (0, _userefstate.getRefValue)(current),
            total: count,
            direction: direction
        }));
    };
    var renderEffect = function renderEffect() {
        if (!effect) return (0, _default.defaultEffect)({
            children: children,
            getSpringsAxis: getSpringsAxis,
            loop: loop,
            count: count,
            isVertical: isVertical
        });
        if (effect && effect.name === 'focus') {
            return (0, _focus.focusEffect)({
                children: children,
                springs: springs,
                loop: loop,
                count: count,
                isVertical: isVertical,
                effect: effect,
                current: current,
                swiperDirection: swiperDirection,
                dragging: dragging,
                transforms: transforms
            });
        }
    };
    var renderSlides = function renderSlides() {
        return /*#__PURE__*/ _react.default.createElement("div", {
            ref: stageRef,
            className: (0, _classnames.default)('nut-swiper-inner', {
                'nut-swiper-inner-vertical': isVertical,
                'nut-swiper-inner-horizontal': !isVertical
            }),
            style: (0, _object_spread._)({}, props.slideSize ? (0, _define_property._)({}, isVertical ? 'height' : 'width', "".concat(props.slideSize, "px")) : {})
        }, renderEffect());
    };
    return /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread._)({
        className: (0, _classnames.default)('nut-swiper', className),
        style: style,
        ref: swiperRef
    }, bind()), renderSlides(), renderIndicator());
});
Swiper.displayName = 'NutSwiper';
