var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
function _extends() {
  _extends = Object.assign ? Object.assign.bind() : 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);
}
import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
import classnames from "classnames";
import { useSpring, animated } from "@react-spring/web";
import { useDrag } from "@use-gesture/react";
import ConfigProviderContext from "../config-provider/ConfigProviderContext";
import { PageIndicator } from "./page-indicator";
import SwiperItem from "./SwiperItem";
import useRefState from "../hooks/use-ref-state";
import { bound } from "../utils/bound";
import { devWarning } from "../utils/dev-log";
import { noop } from "../utils";
import { getRect } from "../hooks/get-rect";
import useMountedRef from "../hooks/use-mounted-ref";
import { mergeFuncProps } from "../utils/with-func-props";
function modulus(value, division) {
  const remainder = value % division;
  return remainder < 0 ? remainder + division : remainder;
}
const eventToPropRecord = {
  mousedown: "onMouseDown",
  mousemove: "onMouseMove",
  mouseup: "onMouseUp"
};
let currentUid;
const Swiper = /* @__PURE__ */ forwardRef((props, ref) => {
  const {
    prefixCls,
    createNamespace
  } = useContext(ConfigProviderContext);
  const [bem] = createNamespace("swiper", prefixCls);
  const {
    loop: outerLoop,
    autoplay,
    direction,
    autoplayInterval
  } = props;
  const [uid] = useState({});
  const lock = useRef(false);
  const trackRef = useRef(null);
  const [root, setRoot] = useState(null);
  const [current, setCurrent] = useState(props.defaultIndex);
  const [dragging, setDragging, draggingRef] = useRefState(false);
  const isVertical = direction === "vertical";
  const axis = useMemo(() => isVertical ? "y" : "x", [isVertical]);
  const slideRatio = props.slideSize / 100;
  const offsetRatio = props.trackOffset / 100;
  const computedStyle = useMemo(() => {
    return __spreadValues({
      [`--${prefixCls}-swipe-slide-size`]: `${props.slideSize}%`,
      [`--${prefixCls}-swipe-track-offset`]: `${props.trackOffset}%`
    }, props.style);
  }, [props.style, props.slideSize, props.trackOffset]);
  const axisDistance = useMemo(() => {
    if (!isVertical)
      return 100;
    const rect = getRect(root);
    return rect.height;
  }, [isVertical, root]);
  const {
    validChildren,
    count
  } = useMemo(() => {
    let innerCount = 0;
    const innerValidChildren = React.Children.map(props.children, (child) => {
      if (!/* @__PURE__ */ React.isValidElement(child))
        return null;
      if (child.type !== SwiperItem) {
        devWarning("Swiper", "The children of `Swiper` must be `Swiper.Item` components.");
        return null;
      }
      innerCount++;
      return child;
    });
    return {
      validChildren: innerValidChildren,
      count: innerCount
    };
  }, [props.children]);
  const loop = useMemo(() => {
    if (count <= 1)
      return false;
    return outerLoop;
  }, [count, outerLoop]);
  const mountedRef = useMountedRef();
  const getSlidePixels = () => {
    const track = trackRef.current;
    if (!track)
      return 0;
    const trackPixels = isVertical ? track.offsetHeight : track.offsetWidth;
    return trackPixels * props.slideSize / 100;
  };
  const boundIndex = (cur) => {
    let min = 0;
    let max = count - 1;
    if (props.stuckAtBoundary) {
      min += (1 - slideRatio - offsetRatio) / slideRatio;
      max -= (1 - slideRatio - offsetRatio) / slideRatio;
    }
    return bound(cur, min, max);
  };
  const [{
    position
  }, api] = useSpring(() => ({
    position: boundIndex(current) * 100,
    config: {
      tension: 200,
      friction: 30,
      autoplayInterval
    },
    onRest: () => {
      if (draggingRef.current)
        return;
      const rawX = position.get();
      const totalWidth = 100 * count;
      const standardPosition = modulus(rawX, totalWidth);
      if (standardPosition === rawX)
        return;
      api.start({
        position: standardPosition,
        immediate: true
      });
    }
  }), [count]);
  const dragCancelRef = useRef(null);
  function forceCancelDrag() {
    var _a;
    (_a = dragCancelRef.current) == null ? void 0 : _a.call(dragCancelRef);
    draggingRef.current = false;
  }
  const bind = useDrag((state) => {
    dragCancelRef.current = state.cancel;
    if (!state.intentional)
      return;
    if (state.first && !currentUid) {
      currentUid = uid;
    }
    if (currentUid !== uid)
      return;
    currentUid = state.last ? void 0 : uid;
    const slidePixels = getSlidePixels();
    if (lock.current)
      return;
    if (!slidePixels)
      return;
    const paramIndex = isVertical ? 1 : 0;
    const offset = state.offset[paramIndex];
    const itemDirection = state.direction[paramIndex];
    const velocity = state.velocity[paramIndex];
    setDragging(true);
    if (!state.last) {
      api.start({
        position: offset * 100 / slidePixels,
        immediate: true
      });
    } else {
      const index = Math.round((offset + Math.min(velocity * 2e3, slidePixels) * itemDirection) / slidePixels);
      swipeTo(index);
      window.setTimeout(() => {
        if (mountedRef.current) {
          setDragging(false);
        }
      });
    }
  }, {
    transform: ([x, y]) => [-x, -y],
    from: () => {
      const slidePixels = getSlidePixels();
      return [position.get() / 100 * slidePixels, position.get() / 100 * slidePixels];
    },
    bounds: () => {
      if (loop)
        return {};
      const slidePixels = getSlidePixels();
      const lowerBound = boundIndex(0) * slidePixels;
      const upperBound = boundIndex(count - 1) * slidePixels;
      return isVertical ? {
        top: lowerBound,
        bottom: upperBound
      } : {
        left: lowerBound,
        right: upperBound
      };
    },
    rubberband: true,
    axis,
    preventScroll: !isVertical,
    pointer: {
      touch: true
    }
  });
  const renderIndicator = () => {
    if (props.indicator === void 0 || props.indicator === true) {
      return /* @__PURE__ */ React.createElement("div", {
        className: classnames(bem("indicator", {
          vertical: isVertical
        }))
      }, /* @__PURE__ */ React.createElement(PageIndicator, _extends({}, props.indicatorProps, {
        direction: props.direction,
        total: count,
        current
      })));
    }
    if (typeof props.indicator === "function") {
      return props.indicator(count, current);
    }
    return null;
  };
  const onClickCapture = (e) => {
    if (draggingRef.current) {
      e.stopPropagation();
    }
    forceCancelDrag();
  };
  function swipeTo(index, immediate = false) {
    var _a, _b;
    if (loop) {
      const i = modulus(index, count);
      setCurrent(i);
      (_a = props.onIndexChange) == null ? void 0 : _a.call(props, i);
      api.start({
        position: index * 100,
        immediate
      });
    } else {
      const i = bound(index, 0, count - 1);
      setCurrent(i);
      (_b = props.onIndexChange) == null ? void 0 : _b.call(props, i);
      api.start({
        position: boundIndex(i) * 100,
        immediate
      });
    }
  }
  const swipeNext = () => {
    swipeTo(Math.round(position.get() / 100) + 1);
  };
  const swipePrev = () => {
    swipeTo(Math.round(position.get() / 100) - 1);
  };
  useImperativeHandle(ref, () => ({
    activeIndex: current,
    swipeTo,
    swipeNext,
    swipePrev,
    lock: () => {
      lock.current = true;
    },
    unlock: () => {
      lock.current = false;
    }
  }));
  useEffect(() => {
    if (!autoplay || dragging)
      return noop;
    const interval = window.setInterval(() => {
      swipeNext();
    }, autoplayInterval);
    return () => {
      window.clearInterval(interval);
    };
  }, [autoplay, dragging, axisDistance]);
  if (count === 0) {
    devWarning("Swiper", "`Swiper` needs at least one child.");
  }
  const dragProps = __spreadValues({}, props.allowTouchMove ? bind() : {});
  const stopPropagationProps = {};
  props.stopPropagation.forEach((key) => {
    const prop = eventToPropRecord[key];
    stopPropagationProps[prop] = function(e) {
      e.stopPropagation();
    };
  });
  const mergedProps = mergeFuncProps(dragProps, stopPropagationProps);
  return /* @__PURE__ */ React.createElement("div", {
    ref: setRoot,
    className: classnames(props.className, bem({
      vertical: isVertical
    })),
    style: computedStyle
  }, /* @__PURE__ */ React.createElement("div", _extends({
    ref: trackRef,
    className: classnames(bem("track", {
      "allow-touch-move": props.allowTouchMove
    })),
    onClickCapture
  }, mergedProps), /* @__PURE__ */ React.createElement("div", {
    className: classnames(bem("track-inner", {
      vertical: isVertical
    }))
  }, React.Children.map(validChildren, (child, index) => {
    return /* @__PURE__ */ React.createElement(animated.div, {
      className: classnames(bem("slide")),
      style: {
        [axis]: position.to((pos) => {
          let finalPosition = -pos + index * 100;
          const totalWidth = count * 100;
          const flagWidth = totalWidth / 2;
          finalPosition = modulus(finalPosition + flagWidth, totalWidth) - flagWidth;
          return `${finalPosition}%`;
        }),
        left: `-${index * 100}%`
      }
    }, child);
  }))), renderIndicator());
});
Swiper.defaultProps = {
  autoplay: false,
  autoplayInterval: 3e3,
  allowTouchMove: true,
  defaultIndex: 0,
  loop: true,
  slideSize: 100,
  stuckAtBoundary: false,
  trackOffset: 0,
  stopPropagation: []
};
Swiper.displayName = "Swiper";
var stdin_default = Swiper;
export {
  stdin_default as default
};
