var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
var stdin_exports = {};
__export(stdin_exports, {
  default: () => stdin_default
});
module.exports = __toCommonJS(stdin_exports);
var import_react = __toESM(require("react"));
var import_classnames = __toESM(require("classnames"));
var import_utils = require("../utils");
var import_use_touch = require("../hooks/use-touch");
var import_use_scroll_parent = require("../hooks/use-scroll-parent");
var import_use_event_listener = __toESM(require("../hooks/use-event-listener"));
var import_loading = __toESM(require("../loading"));
var import_hooks = require("../hooks");
var import_ConfigProviderContext = __toESM(require("../config-provider/ConfigProviderContext"));
const DEFAULT_HEAD_HEIGHT = 50;
const TEXT_STATUS = ["pulling", "loosing", "success"];
const PullRefresh = (props) => {
  const {
    prefixCls,
    createNamespace
  } = (0, import_react.useContext)(import_ConfigProviderContext.default);
  const [bem] = createNamespace("pull-refresh", prefixCls);
  const {
    disabled,
    animationDuration
  } = props;
  const root = (0, import_react.useRef)();
  const [state, updateState] = (0, import_hooks.useSetState)({
    refreshing: false,
    status: "normal",
    distance: 0,
    duration: 0
  });
  const track = (0, import_react.useRef)();
  const reachTop = (0, import_react.useRef)(null);
  const touch = (0, import_use_touch.useTouch)();
  const getHeadStyle = () => {
    if (props.headHeight !== DEFAULT_HEAD_HEIGHT) {
      return {
        height: `${props.headHeight}px`
      };
    }
    return null;
  };
  const isTouchable = (0, import_react.useCallback)(() => {
    return state.status !== "loading" && state.status !== "success" && !disabled;
  }, [state.status, disabled]);
  const ease = (distance) => {
    const pullDistance = +(props.pullDistance || props.headHeight);
    if (distance > pullDistance) {
      if (distance < pullDistance * 2) {
        distance = pullDistance + (distance - pullDistance) / 2;
      } else {
        distance = pullDistance * 1.5 + (distance - pullDistance * 2) / 4;
      }
    }
    return Math.round(distance);
  };
  const setStatus = (distance, isLoading) => {
    const pullDistance = +(props.pullDistance || props.headHeight);
    const newState = {
      distance
    };
    if (isLoading) {
      newState.status = "loading";
    } else if (distance === 0) {
      newState.status = "normal";
    } else if (distance < pullDistance) {
      newState.status = "pulling";
    } else {
      newState.status = "loosing";
    }
    updateState(newState);
  };
  const getStatusText = () => {
    if (state.status === "normal") {
      return "";
    }
    return props[`${state.status}Text`];
  };
  const renderStatus = () => {
    const {
      status,
      distance
    } = state;
    if (typeof props[`${state.status}Text`] === "function") {
      return props[`${state.status}Text`]({
        distance
      });
    }
    const nodes = [];
    if (TEXT_STATUS.includes(status)) {
      nodes.push(/* @__PURE__ */ import_react.default.createElement("div", {
        key: "text",
        className: (0, import_classnames.default)(bem("text"))
      }, getStatusText()));
    }
    if (status === "loading") {
      nodes.push(/* @__PURE__ */ import_react.default.createElement(import_loading.default, {
        key: "loading",
        className: (0, import_classnames.default)(bem("loading"))
      }, getStatusText()));
    }
    return nodes;
  };
  const showSuccessTip = () => {
    updateState({
      status: "success"
    });
    setTimeout(() => {
      setStatus(0);
    }, +props.successDuration);
  };
  const onRefresh = () => __async(void 0, null, function* () {
    try {
      updateState({
        refreshing: true
      });
      yield props.onRefresh();
      updateState({
        refreshing: false
      });
    } catch (error) {
      updateState({
        refreshing: false
      });
    }
  });
  const checkPosition = (event) => {
    const scrollTarget = (0, import_use_scroll_parent.getScrollParent)(event.target);
    reachTop.current = (0, import_utils.getScrollTop)(scrollTarget) === 0;
    if (reachTop.current) {
      updateState({
        duration: 0
      });
      touch.start(event);
    }
  };
  const onTouchStart = (event) => {
    if (isTouchable()) {
      checkPosition(event.nativeEvent);
    }
  };
  const onTouchMove = (0, import_react.useCallback)((event) => {
    if (isTouchable()) {
      if (!reachTop.current) {
        checkPosition(event);
      }
      touch.move(event);
      if (reachTop.current && touch.deltaY.current >= 0 && touch.isVertical()) {
        setStatus(ease(touch.deltaY.current));
        (0, import_utils.preventDefault)(event);
      } else {
        setStatus(0);
      }
    }
  }, [reachTop.current, touch.deltaY, isTouchable]);
  const onTouchEnd = () => __async(void 0, null, function* () {
    if (reachTop.current && touch.deltaY && isTouchable()) {
      updateState({
        duration: +animationDuration
      });
      if (state.status === "loosing") {
        setStatus(+props.headHeight, true);
        onRefresh();
      } else {
        setStatus(0);
      }
    }
  });
  (0, import_use_event_listener.default)("touchmove", onTouchMove, {
    target: track.current,
    depends: [reachTop.current, isTouchable(), touch.deltaY]
  });
  (0, import_hooks.useUpdateEffect)(() => {
    updateState({
      duration: +animationDuration
    });
    if (state.refreshing) {
      setStatus(+props.headHeight, true);
    } else if (props.successText) {
      showSuccessTip();
    } else {
      setStatus(0, false);
    }
  }, [state.refreshing]);
  const trackStyle = (0, import_react.useMemo)(() => ({
    transitionDuration: `${state.duration}ms`,
    transform: state.distance ? `translate3d(0,${state.distance}px, 0)` : ""
  }), [state.duration, state.distance]);
  return /* @__PURE__ */ import_react.default.createElement("div", {
    ref: root,
    className: (0, import_classnames.default)(props.className, bem()),
    style: props.style
  }, /* @__PURE__ */ import_react.default.createElement("div", {
    ref: track,
    className: (0, import_classnames.default)(bem("track")),
    style: trackStyle,
    onTouchStart,
    onTouchEnd,
    onTouchCancel: onTouchEnd
  }, /* @__PURE__ */ import_react.default.createElement("div", {
    className: (0, import_classnames.default)(bem("head")),
    style: getHeadStyle()
  }, renderStatus()), props.children));
};
PullRefresh.defaultProps = {
  headHeight: 50,
  animationDuration: 300,
  successDuration: 500,
  pullingText: "\u4E0B\u62C9\u5373\u53EF\u5237\u65B0...",
  loosingText: "\u91CA\u653E\u5373\u53EF\u5237\u65B0...",
  loadingText: "\u52A0\u8F7D\u4E2D..."
};
var stdin_default = PullRefresh;
