"use strict";

exports.__esModule = true;
exports.default = void 0;

var _react = _interopRequireWildcard(require("react"));

var _clsx = _interopRequireDefault(require("clsx"));

var _web = require("@react-spring/web");

var _react2 = require("@use-gesture/react");

var _ConfigProviderContext = _interopRequireDefault(require("../config-provider/ConfigProviderContext"));

var _SwiperItem = _interopRequireDefault(require("./SwiperItem"));

var _useRefs2 = _interopRequireDefault(require("../hooks/use-refs"));

var _useRefState2 = _interopRequireDefault(require("../hooks/use-ref-state"));

var _bound = require("../utils/bound");

var _devLog = require("../utils/dev-log");

var _utils = require("../utils");

var _SwiperPagIndicator = _interopRequireDefault(require("./SwiperPagIndicator"));

var _hooks = require("../hooks");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

var Swiper = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
  var _useContext = (0, _react.useContext)(_ConfigProviderContext.default),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace;

  var _createNamespace = createNamespace('swiper', prefixCls),
      bem = _createNamespace[0];

  var outerLoop = props.loop,
      autoplay = props.autoplay,
      vertical = props.vertical,
      duration = props.duration,
      autoHeight = props.autoHeight;
  var axis = vertical ? 'y' : 'x';
  var slideRatio = props.slideSize / 100;
  var offsetRatio = props.trackOffset / 100;

  var _useMemo = (0, _react.useMemo)(function () {
    var innerCount = 0;

    var innerValidChildren = _react.default.Children.map(props.children, function (child) {
      if (! /*#__PURE__*/_react.default.isValidElement(child)) return null;

      if (child.type !== _SwiperItem.default) {
        (0, _devLog.devWarning)('Swiper', 'The children of `Swiper` must be `Swiper.Item` components.');
        return null;
      }

      innerCount++;
      return child;
    });

    return {
      validChildren: innerValidChildren,
      count: innerCount
    };
  }, [props.children]),
      validChildren = _useMemo.validChildren,
      count = _useMemo.count;

  var trackRef = (0, _react.useRef)(null);

  var _useRefs = (0, _useRefs2.default)(),
      childrenRefs = _useRefs[0],
      setChildrenRefs = _useRefs[1];

  var _useState = (0, _react.useState)(function () {
    return props.enabled;
  }),
      enabled = _useState[0],
      setEnabled = _useState[1];

  var _useState2 = (0, _react.useState)(props.initialSwipe),
      current = _useState2[0],
      setCurrent = _useState2[1];

  var _useRefState = (0, _useRefState2.default)(false),
      dragging = _useRefState[0],
      setDragging = _useRefState[1],
      draggingRef = _useRefState[2];

  var computedStyle = (0, _react.useMemo)(function () {
    var _extends2;

    return _extends((_extends2 = {}, _extends2["--" + prefixCls + "-swipe-slide-size"] = props.slideSize + "%", _extends2["--" + prefixCls + "-swipe-track-offset"] = props.trackOffset + "%", _extends2), props.style);
  }, [prefixCls, props.slideSize, props.trackOffset, props.style]);
  var trackStyle = (0, _react.useMemo)(function () {
    if (!autoHeight) return {};
    var target = childrenRefs[current];
    if (target) return {
      height: target.getHeight() || 'auto'
    };
    return {}; // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoHeight, childrenRefs.length, current]);
  var loop = (0, _react.useMemo)(function () {
    if (slideRatio * (count - 1) < 1) return false;
    return outerLoop;
  }, [count, outerLoop, slideRatio]);

  var getSlidePixels = function getSlidePixels() {
    var track = trackRef.current;
    if (!track) return 0;
    var trackPixels = vertical ? track.offsetHeight : track.offsetWidth;
    return trackPixels * props.slideSize / 100;
  };

  var boundIndex = function boundIndex(cur) {
    var min = 0;
    var max = count - 1;

    if (props.stuckAtBoundary) {
      min += (1 - slideRatio - offsetRatio) / slideRatio;
      max -= (1 - slideRatio - offsetRatio) / slideRatio;
    }

    return (0, _bound.bound)(cur, min, max);
  };

  var _useSpring = (0, _web.useSpring)(function () {
    return {
      position: boundIndex(current) * 100,
      config: {
        tension: 200,
        friction: 30,
        duration: duration
      },
      onRest: function onRest() {
        if (draggingRef.current) return;
        if (!loop) return;
        var rawX = position.get();
        var totalWidth = 100 * count;
        var standardPosition = modulus(rawX, totalWidth);
        if (standardPosition === rawX) return;
        api.start({
          position: standardPosition,
          immediate: true
        });
      }
    };
  }, [count]),
      position = _useSpring[0].position,
      api = _useSpring[1];

  var bind = (0, _react2.useDrag)(function (state) {
    var _childrenRefs$current;

    var slidePixels = getSlidePixels();
    if (!slidePixels) return;

    if (!props.preventScroll && isScrollTarget(state.target, (_childrenRefs$current = childrenRefs[current]) == null ? void 0 : _childrenRefs$current.self)) {
      return;
    }

    var paramIndex = vertical ? 1 : 0;
    var offset = state.offset[paramIndex];
    var direction = state.direction[paramIndex];
    var velocity = state.velocity[paramIndex];
    setDragging(true);

    if (!state.last) {
      api.start({
        position: offset * 100 / slidePixels,
        immediate: true
      });
    } else {
      var index = Math.round((offset + Math.min(velocity * 2000, slidePixels) * direction) / slidePixels);
      swipeTo(index);
      window.setTimeout(function () {
        setDragging(false);
      });
    }
  }, {
    enabled: enabled,
    transform: function transform(_ref) {
      var x = _ref[0],
          y = _ref[1];
      return [-x, -y];
    },
    from: function from() {
      var slidePixels = getSlidePixels();
      return [position.get() / 100 * slidePixels, position.get() / 100 * slidePixels];
    },
    bounds: function bounds() {
      if (loop) return {};
      var slidePixels = getSlidePixels();
      var lowerBound = boundIndex(0) * slidePixels;
      var upperBound = boundIndex(count - 1) * slidePixels;
      return vertical ? {
        top: lowerBound,
        bottom: upperBound
      } : {
        left: lowerBound,
        right: upperBound
      };
    },
    rubberband: props.rubberband,
    axis: axis,
    preventScroll: axis === 'x' ? props.preventScroll : false,
    pointer: {
      touch: true
    }
  });

  var renderIndicator = function renderIndicator() {
    if (props.indicator === undefined || props.indicator === true) {
      return /*#__PURE__*/_react.default.createElement("div", {
        className: (0, _clsx.default)(bem('indicator', {
          vertical: vertical
        }))
      }, /*#__PURE__*/_react.default.createElement(_SwiperPagIndicator.default, _extends({}, props.indicatorProps, {
        vertical: vertical,
        total: count,
        current: current
      })));
    }

    if (typeof props.indicator === 'function') {
      return props.indicator(count, current);
    }

    return null;
  };

  function swipeTo(index, immediate) {
    if (immediate === void 0) {
      immediate = false;
    }

    var roundedIndex = Math.round(index);
    var targetIndex = loop ? modulus(roundedIndex, count) : (0, _bound.bound)(roundedIndex, 0, count - 1);
    setCurrent(targetIndex);
    api.start({
      position: (loop ? roundedIndex : boundIndex(roundedIndex)) * 100,
      immediate: immediate
    });
  }

  var swipeNext = function swipeNext() {
    swipeTo(Math.round(position.get() / 100) + 1);
  };

  var swipePrev = function swipePrev() {
    swipeTo(Math.round(position.get() / 100) - 1);
  };

  (0, _react.useImperativeHandle)(ref, function () {
    return {
      activeIndex: current,
      swipeTo: swipeTo,
      swipeNext: swipeNext,
      swipePrev: swipePrev,
      enable: function enable() {
        setEnabled(true);
      },
      disable: function disable() {
        setEnabled(false);
      }
    };
  });
  (0, _hooks.useIsomorphicLayoutEffect)(function () {
    var maxIndex = validChildren.length - 1;

    if (current > maxIndex) {
      swipeTo(maxIndex, true);
    }
  });
  (0, _hooks.useUpdateEffect)(function () {
    props.onChange == null ? void 0 : props.onChange(current);
  }, [current]);
  (0, _react.useEffect)(function () {
    if (!autoplay || dragging) return _utils.noop;
    var autoplayInterval = typeof autoplay === 'boolean' ? 5000 : autoplay;
    var interval = window.setInterval(function () {
      swipeNext();
    }, autoplayInterval);
    return function () {
      window.clearInterval(interval);
    }; // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoplay, dragging]);

  var renderTrackInner = function renderTrackInner() {
    var _style2;

    if (loop) {
      return /*#__PURE__*/_react.default.createElement("div", {
        className: (0, _clsx.default)(bem('track-inner', {
          vertical: vertical
        })),
        style: trackStyle
      }, _react.default.Children.map(validChildren, function (child, index) {
        var _style;

        return /*#__PURE__*/_react.default.createElement(_web.animated.div, {
          className: (0, _clsx.default)(bem('slide')),
          style: (_style = {}, _style[axis] = position.to(function (pos) {
            var finalPosition = -pos + index * 100;
            var totalWidth = count * 100;
            var flagWidth = totalWidth / 2;
            finalPosition = modulus(finalPosition + flagWidth, totalWidth) - flagWidth;
            return finalPosition + "%";
          }), _style[vertical ? 'top' : 'left'] = "-" + index * 100 + "%", _style)
        }, /*#__PURE__*/_react.default.cloneElement(child, {
          ref: setChildrenRefs(index)
        }));
      }));
    }

    return /*#__PURE__*/_react.default.createElement(_web.animated.div, {
      className: (0, _clsx.default)(bem('track-inner')),
      style: (_style2 = {}, _style2[axis] = position.to(function (position) {
        return -position + "%";
      }), _style2)
    }, _react.default.Children.map(validChildren, function (child, index) {
      return /*#__PURE__*/_react.default.createElement("div", {
        className: (0, _clsx.default)(bem('slide'))
      }, /*#__PURE__*/_react.default.cloneElement(child, {
        ref: setChildrenRefs(index)
      }));
    }));
  };

  if (count === 0) {
    (0, _devLog.devWarning)('Swiper', '`Swiper` needs at least one child.');
  }

  return /*#__PURE__*/_react.default.createElement("div", {
    className: (0, _clsx.default)(props.className, bem({
      vertical: vertical
    })),
    style: computedStyle
  }, /*#__PURE__*/_react.default.createElement("div", _extends({
    ref: trackRef,
    className: (0, _clsx.default)(bem('track', {
      'allow-touch-move': props.touchable
    })),
    onClickCapture: function onClickCapture(e) {
      if (draggingRef.current) {
        e.stopPropagation();
      }
    }
  }, props.touchable ? bind() : {}), renderTrackInner()), renderIndicator());
}); // defaultProps defined if need

Swiper.defaultProps = {
  initialSwipe: 0,
  touchable: true,
  enabled: true,
  rubberband: true,
  autoplay: false,
  slideSize: 100,
  trackOffset: 0,
  stuckAtBoundary: false,
  preventScroll: true
};
var _default = Swiper;
exports.default = _default;

function modulus(value, division) {
  var remainder = value % division;
  return remainder < 0 ? remainder + division : remainder;
}

function isScrollTarget(element, parent) {
  if (!parent) return false;

  if (element.scrollWidth > element.clientWidth || element.scrollHeight > element.clientHeight) {
    return true;
  }

  if (element.parentElement && element.parentElement !== parent) {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    return isScrollTarget(element.parentElement, parent);
  }

  return false;
}