"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ForceScrollDownView = void 0;
var _react = require("react");
var _reactNative = require("react-native");
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
var _reactNativeWorklets = require("react-native-worklets");
var _core = require("../../core");
var _buttons = require("../buttons");
var _layout = require("../layout");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
/**
 * A React Native component that displays a scroll view with a button that scrolls to the bottom of the content
 * when pressed. The button is hidden when the scroll view reaches a certain threshold from the bottom, which is
 * configurable by the `threshold` prop. The button, and the scrolling, can also be disabled by setting the
 * `scrollEnabled` prop to `false`.
 */
const ForceScrollDownView = ({
  footerActions,
  children,
  threshold: customThreshold,
  style,
  contentContainerStyle,
  scrollEnabled = true,
  onThresholdCrossed,
  animatedRef
}) => {
  const internalAnimatedRef = (0, _reactNativeReanimated.useAnimatedRef)();
  const scrollViewRef = animatedRef ?? internalAnimatedRef;
  const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
  const {
    footerActionsInlineMeasurements,
    handleFooterActionsInlineMeasurements
  } = (0, _layout.useFooterActionsInlineMeasurements)();
  const threshold = footerActions ? footerActionsInlineMeasurements.safeBottomAreaHeight : customThreshold;

  /**
   * Whether or not the "scroll to bottom" button should be visible. This is controlled by the threshold
   * and the current scroll position.
   */
  // const [isButtonVisible, setButtonVisible] = useState(true);

  const isButtonVisible = (0, _reactNativeReanimated.useSharedValue)(1);
  const scrollViewHeight = (0, _reactNativeReanimated.useSharedValue)(0);
  const contentHeight = (0, _reactNativeReanimated.useSharedValue)(0);
  const offsetY = (0, _reactNativeReanimated.useScrollOffset)(scrollViewRef);
  (0, _reactNativeReanimated.useAnimatedReaction)(() => scrollViewHeight.value + Math.max(offsetY.value, 0) >= contentHeight.value - (threshold ?? 0), (crossed, previous) => {
    if (crossed !== previous) {
      // eslint-disable-next-line functional/immutable-data
      isButtonVisible.value = (0, _reactNativeReanimated.withSpring)(crossed && scrollEnabled ? 0 : 1, _core.IOSpringValues.button);
      if (onThresholdCrossed) {
        (0, _reactNativeWorklets.scheduleOnRN)(onThresholdCrossed, crossed);
      }
    }
  });

  /**
   * A callback that is called whenever the size of the scrollable content changes. It updates the
   * state with the new content height.
   */
  const handleContentSizeChange = (0, _react.useCallback)(
  // eslint-disable-next-line functional/immutable-data
  (_w, h) => contentHeight.value = h, [contentHeight]);

  /**
   * A callback that is called whenever the size of the scroll view changes. It updates the state
   * with the new scroll view height.
   */
  const handleLayout = (0, _react.useCallback)(event =>
  // eslint-disable-next-line functional/immutable-data
  scrollViewHeight.value = event.nativeEvent.layout.height, [scrollViewHeight]);

  /**
   * A callback that is called when the "scroll to bottom" button is pressed. It scrolls the
   * scroll view to the bottom and hides the button.
   */
  const handleScrollDownPress = (0, _react.useCallback)(() => {
    (0, _reactNativeWorklets.scheduleOnUI)(() => {
      "worklet";

      // eslint-disable-next-line functional/immutable-data
      isButtonVisible.value = (0, _reactNativeReanimated.withSpring)(0, _core.IOSpringValues.button);
      const targetY = Math.max(0, contentHeight.value - scrollViewHeight.value);
      (0, _reactNativeReanimated.scrollTo)(scrollViewRef, 0, targetY, true);
    });
  }, [scrollViewRef, contentHeight, scrollViewHeight, isButtonVisible]);

  /**
   * The "scroll to bottom" button component. It is wrapped in a reanimated View
   * and has animated style applied to it.
   */

  const buttonTransitionStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
    const androidEdgeToEdgeMargin = _reactNative.Platform.OS === "ios" ? 0 : insets.bottom;
    return {
      bottom: _core.IOVisualCostants.scrollDownButtonBottom + androidEdgeToEdgeMargin,
      opacity: isButtonVisible.value,
      transform: [{
        scale: (0, _reactNativeReanimated.interpolate)(isButtonVisible.value, [0, 1], [0.5, 1])
      }]
    };
  });
  const scrollDownButton = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
    style: [styles.scrollDownButton, buttonTransitionStyle],
    children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_buttons.IconButtonSolid, {
      testID: "ScrollDownButton",
      accessibilityLabel: "Scroll to bottom",
      icon: "arrowBottom",
      onPress: handleScrollDownPress
    })
  });
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
    children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.ScrollView, {
      testID: "ScrollView",
      ref: scrollViewRef,
      scrollEnabled: scrollEnabled,
      style: style,
      onLayout: handleLayout,
      onContentSizeChange: handleContentSizeChange,
      contentContainerStyle: contentContainerStyle,
      children: [children, footerActions && /*#__PURE__*/(0, _jsxRuntime.jsx)(_layout.FooterActions, {
        ...footerActions,
        onMeasure: handleFooterActionsInlineMeasurements,
        fixed: false
      })]
    }), scrollDownButton]
  });
};
exports.ForceScrollDownView = ForceScrollDownView;
const styles = _reactNative.StyleSheet.create({
  scrollDownButton: {
    position: "absolute",
    zIndex: 10,
    right: _core.IOVisualCostants.scrollDownButtonRight
  }
});
//# sourceMappingURL=ForceScrollDownView.js.map