"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _reactNativeGestureHandler = require("react-native-gesture-handler");
var _reactNativeKeyboardController = require("react-native-keyboard-controller");
var _reactNativeReanimated = _interopRequireWildcard(require("react-native-reanimated"));
var _reactNativeSafeAreaContext = require("react-native-safe-area-context");
var _useThemeColors = require("../hooks/useThemeColors");
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); }
const {
  width: SCREEN_WIDTH,
  height: SCREEN_HEIGHT
} = _reactNative.Dimensions.get('window');
const SPRING_CONFIG = {
  damping: 25,
  stiffness: 300,
  mass: 0.8
};
const BottomSheet = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
  const {
    children,
    onDismiss,
    enablePanDownToClose = true,
    backgroundComponent,
    backdropComponent,
    style,
    enableHandlePanningGesture = true,
    onDismissAttempt,
    detached = false
  } = props;
  const insets = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
  const colors = (0, _useThemeColors.useThemeColors)();
  const [visible, setVisible] = (0, _react.useState)(false);
  const [rendered, setRendered] = (0, _react.useState)(false); // keep mounted for exit animation
  const closeTimeoutRef = (0, _react.useRef)(null);
  const hasClosedRef = (0, _react.useRef)(false);
  const scrollViewRef = (0, _react.useRef)(null);
  const translateY = (0, _reactNativeReanimated.useSharedValue)(SCREEN_HEIGHT);
  const opacity = (0, _reactNativeReanimated.useSharedValue)(0);
  const scrollOffsetY = (0, _reactNativeReanimated.useSharedValue)(0);
  const isScrollAtTop = (0, _reactNativeReanimated.useSharedValue)(true);
  const allowPanClose = (0, _reactNativeReanimated.useSharedValue)(true);
  const keyboardHeight = (0, _reactNativeReanimated.useSharedValue)(0);
  const context = (0, _reactNativeReanimated.useSharedValue)({
    y: 0
  });
  (0, _reactNativeKeyboardController.useKeyboardHandler)({
    onMove: e => {
      'worklet';

      keyboardHeight.value = e.height;
    },
    onEnd: e => {
      'worklet';

      keyboardHeight.value = e.height;
    }
  }, []);

  // Dismiss callbacks
  const safeClose = () => {
    if (onDismissAttempt?.()) {
      onDismiss?.();
    } else if (!onDismissAttempt) {
      onDismiss?.();
    }
  };
  const finishClose = (0, _react.useCallback)(() => {
    if (hasClosedRef.current) return;
    hasClosedRef.current = true;
    safeClose();
    setRendered(false);
  }, [safeClose]);
  (0, _react.useEffect)(() => {
    if (visible) {
      if (closeTimeoutRef.current) {
        clearTimeout(closeTimeoutRef.current);
        closeTimeoutRef.current = null;
      }
      hasClosedRef.current = false;
      opacity.value = (0, _reactNativeReanimated.withTiming)(1, {
        duration: 250
      });
      translateY.value = (0, _reactNativeReanimated.withSpring)(0, SPRING_CONFIG);
    } else if (rendered) {
      opacity.value = (0, _reactNativeReanimated.withTiming)(0, {
        duration: 250
      }, finished => {
        if (finished) {
          (0, _reactNativeReanimated.runOnJS)(finishClose)();
        }
      });
      translateY.value = (0, _reactNativeReanimated.withSpring)(SCREEN_HEIGHT, {
        ...SPRING_CONFIG,
        stiffness: 250
      });

      // Fallback timer to ensure close completes (especially on web)
      if (closeTimeoutRef.current) {
        clearTimeout(closeTimeoutRef.current);
      }
      closeTimeoutRef.current = setTimeout(() => {
        finishClose();
        closeTimeoutRef.current = null;
      }, 300);
    }
  }, [visible, rendered, finishClose]);

  // Clear pending timeout on unmount
  (0, _react.useEffect)(() => () => {
    if (closeTimeoutRef.current) {
      clearTimeout(closeTimeoutRef.current);
      closeTimeoutRef.current = null;
    }
  }, []);

  // Apply web scrollbar styles when colors change
  (0, _react.useEffect)(() => {
    if (_reactNative.Platform.OS === 'web') {
      createWebScrollbarStyle(colors.border);
    }
  }, [colors.border]);
  const present = (0, _react.useCallback)(() => {
    setRendered(true);
    setVisible(true);
  }, []);
  const dismiss = (0, _react.useCallback)(() => {
    setVisible(false);
  }, []);
  const scrollTo = (0, _react.useCallback)((y, animated = true) => {
    scrollViewRef.current?.scrollTo({
      y,
      animated
    });
  }, []);
  (0, _react.useImperativeHandle)(ref, () => ({
    present,
    dismiss,
    close: dismiss,
    expand: present,
    collapse: dismiss,
    scrollTo
  }), [present, dismiss, scrollTo]);
  const nativeGesture = (0, _react.useMemo)(() => _reactNativeGestureHandler.Gesture.Native(), []);
  const panGesture = _reactNativeGestureHandler.Gesture.Pan().enabled(enablePanDownToClose).simultaneousWithExternalGesture(nativeGesture).onStart(() => {
    'worklet';

    context.value = {
      y: translateY.value
    };
    allowPanClose.value = scrollOffsetY.value <= 8;
  }).onUpdate(event => {
    'worklet';

    if (!allowPanClose.value) {
      return;
    }
    const newTranslateY = context.value.y + event.translationY;
    // If user is scrolling down while content isn't at (or near) the top, let ScrollView handle it
    const atTopOrNearTop = scrollOffsetY.value <= 8; // slightly larger tolerance for smoother handoff
    if (event.translationY > 0 && !atTopOrNearTop) {
      return;
    }
    if (newTranslateY >= 0) {
      translateY.value = newTranslateY;
    } else if (detached) {
      // Only allow overdrag (pulling up beyond top) when detached
      translateY.value = newTranslateY * 0.3;
    } else {
      // In normal mode, prevent overdrag - clamp to 0
      translateY.value = 0;
    }
  }).onEnd(event => {
    'worklet';

    if (!allowPanClose.value) {
      return;
    }
    const velocity = event.velocityY;
    const distance = translateY.value;
    // Require a deeper pull to close (more like native bottom sheets)
    const closeThreshold = Math.max(140, SCREEN_HEIGHT * 0.25);
    const fastSwipeThreshold = 900;
    const shouldClose = velocity > fastSwipeThreshold || distance > closeThreshold && velocity > -300;
    if (shouldClose) {
      translateY.value = (0, _reactNativeReanimated.withSpring)(SCREEN_HEIGHT, {
        ...SPRING_CONFIG,
        velocity: velocity
      });
      opacity.value = (0, _reactNativeReanimated.withTiming)(0, {
        duration: 250
      }, finished => {
        if (finished) {
          (0, _reactNativeReanimated.runOnJS)(finishClose)();
        }
      });
    } else {
      translateY.value = (0, _reactNativeReanimated.withSpring)(0, {
        ...SPRING_CONFIG,
        velocity: velocity
      });
    }
  });
  const backdropStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
    opacity: opacity.value
  }));
  const sheetStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
    const scale = (0, _reactNativeReanimated.interpolate)(translateY.value, [0, SCREEN_HEIGHT], [1, 0.95]);
    return {
      transform: [{
        translateY: translateY.value - keyboardHeight.value
      }, {
        scale
      }]
    };
  });
  const sheetHeightStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => ({
    maxHeight: SCREEN_HEIGHT - keyboardHeight.value - insets.top - (detached ? insets.bottom + 16 : 0)
  }), [insets.top, insets.bottom, detached]);
  const sheetMarginStyle = (0, _reactNativeReanimated.useAnimatedStyle)(() => {
    // Only add margin when detached, otherwise extend behind safe area
    if (detached) {
      return {
        marginBottom: keyboardHeight.value > 0 ? 16 : insets.bottom + 16
      };
    }
    return {
      marginBottom: 0
    };
  }, [insets.bottom, detached]);
  const handleBackdropPress = (0, _react.useCallback)(() => {
    // Always animate close on backdrop press
    if (onDismissAttempt && !onDismissAttempt()) {
      return;
    }
    dismiss();
  }, [onDismissAttempt, dismiss]);
  const scrollHandler = (0, _reactNativeReanimated.useAnimatedScrollHandler)({
    onScroll: event => {
      scrollOffsetY.value = event.contentOffset.y;
      isScrollAtTop.value = event.contentOffset.y <= 0;
    }
  });
  const dynamicStyles = (0, _react.useMemo)(() => {
    const isDark = colors.background === '#000000';
    return _reactNative.StyleSheet.create({
      handle: {
        ...styles.handle,
        backgroundColor: isDark ? '#444' : '#C7C7CC'
      },
      sheet: {
        ...styles.sheet,
        backgroundColor: colors.background,
        ...(detached ? styles.sheetDetached : styles.sheetNormal)
      },
      scrollContent: {
        ...styles.scrollContent
        // In normal mode, don't add padding here - screens handle their own padding
        // The sheet extends behind safe area, and screens add padding as needed
      }
    });
  }, [colors.background, detached, insets.bottom]);
  if (!rendered) return null;
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
    visible: rendered,
    transparent: true,
    animationType: "none",
    statusBarTranslucent: true,
    onRequestClose: dismiss,
    children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeGestureHandler.GestureHandlerRootView, {
      style: _reactNative.StyleSheet.absoluteFill,
      children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
        style: [styles.backdrop, backdropStyle],
        children: backdropComponent ? backdropComponent({
          onPress: handleBackdropPress
        }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
          style: styles.backdropTouchable,
          onPress: handleBackdropPress,
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
            style: _reactNative.StyleSheet.absoluteFill
          })
        })
      }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
        gesture: panGesture,
        children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNativeReanimated.default.View, {
          style: [dynamicStyles.sheet, sheetMarginStyle, sheetStyle, sheetHeightStyle],
          children: [backgroundComponent?.({
            style: styles.background
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
            style: dynamicStyles.handle
          }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
            gesture: nativeGesture,
            children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.ScrollView, {
              ref: scrollViewRef,
              style: [styles.scrollView, _reactNative.Platform.OS === 'web' && {
                scrollbarWidth: 'thin',
                scrollbarColor: `${colors.border} transparent`
              }],
              contentContainerStyle: dynamicStyles.scrollContent,
              showsVerticalScrollIndicator: false,
              keyboardShouldPersistTaps: "handled",
              onScroll: scrollHandler,
              scrollEventThrottle: 16
              // @ts-ignore - Web className
              ,
              className: _reactNative.Platform.OS === 'web' ? 'bottom-sheet-scrollview' : undefined,
              onLayout: () => {
                if (_reactNative.Platform.OS === 'web') {
                  createWebScrollbarStyle(colors.border);
                }
              },
              children: children
            })
          })]
        })
      })]
    })
  });
});
BottomSheet.displayName = 'BottomSheet';
const styles = _reactNative.StyleSheet.create({
  backdrop: {
    flex: 1,
    backgroundColor: 'rgba(0, 0, 0, 0.5)'
  },
  backdropTouchable: {
    flex: 1
  },
  sheet: {
    position: 'absolute',
    bottom: 0,
    overflow: 'hidden',
    maxWidth: 800,
    alignSelf: 'center',
    marginHorizontal: 'auto'
  },
  sheetDetached: {
    left: 16,
    right: 16,
    borderRadius: 24
  },
  sheetNormal: {
    left: 0,
    right: 0,
    borderTopLeftRadius: 24,
    borderTopRightRadius: 24
  },
  handle: {
    position: 'absolute',
    top: 10,
    left: '50%',
    marginLeft: -18,
    width: 36,
    height: 5,
    borderRadius: 3,
    zIndex: 100
  },
  background: {
    ..._reactNative.StyleSheet.absoluteFillObject
  },
  scrollView: {
    flex: 1
  },
  scrollContent: {
    flexGrow: 1
  }
});

// Create web scrollbar styles dynamically based on theme
const createWebScrollbarStyle = borderColor => {
  if (_reactNative.Platform.OS !== 'web' || typeof document === 'undefined') return;
  const styleId = 'bottom-sheet-scrollbar-style';
  let styleElement = document.getElementById(styleId);
  if (!styleElement) {
    styleElement = document.createElement('style');
    styleElement.id = styleId;
    document.head.appendChild(styleElement);
  }

  // Use theme border color for scrollbar
  const scrollbarColor = borderColor;
  const scrollbarHoverColor = borderColor === '#E5E5EA' ? '#C7C7CC' : '#555';
  styleElement.textContent = `
        .bottom-sheet-scrollview::-webkit-scrollbar {
            width: 6px;
        }
        .bottom-sheet-scrollview::-webkit-scrollbar-track {
            background: transparent;
            border-radius: 10px;
        }
        .bottom-sheet-scrollview::-webkit-scrollbar-thumb {
            background: ${scrollbarColor};
            border-radius: 10px;
        }
        .bottom-sheet-scrollview::-webkit-scrollbar-thumb:hover {
            background: ${scrollbarHoverColor};
        }
    `;
};
var _default = exports.default = BottomSheet;
//# sourceMappingURL=BottomSheet.js.map