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); }
/* eslint-disable camelcase */
import * as React from 'react';
import { Animated, Platform, StyleSheet } from 'react-native';
// @ts-ignore Getting private component
// eslint-disable-next-line import/no-named-as-default, import/default, import/no-named-as-default-member, import/namespace
import AppContainer from 'react-native/Libraries/ReactNative/AppContainer';
import warnOnce from 'warn-once';
import ScreenStack from '../../components/ScreenStack';
import ScreenContentWrapper from '../../components/ScreenContentWrapper';
import { ScreenContext } from '../../components/Screen';
import { StackActions, useTheme } from '@react-navigation/native';
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
import HeaderConfig from './HeaderConfig';
import SafeAreaProviderCompat from '../utils/SafeAreaProviderCompat';
import getDefaultHeaderHeight from '../utils/getDefaultHeaderHeight';
import getStatusBarHeight from '../utils/getStatusBarHeight';
import HeaderHeightContext from '../utils/HeaderHeightContext';
import AnimatedHeaderHeightContext from '../utils/AnimatedHeaderHeightContext';
import FooterComponent from './FooterComponent';
const isAndroid = Platform.OS === 'android';
let Container = ScreenContentWrapper;
if (__DEV__) {
  const DebugContainer = props => {
    const {
      stackPresentation,
      ...rest
    } = props;
    if (Platform.OS === 'ios' && stackPresentation !== 'push' && stackPresentation !== 'formSheet') {
      return /*#__PURE__*/React.createElement(AppContainer, null, /*#__PURE__*/React.createElement(ScreenContentWrapper, rest));
    }
    return /*#__PURE__*/React.createElement(ScreenContentWrapper, rest);
  };
  // @ts-ignore Wrong props
  Container = DebugContainer;
}
const MaybeNestedStack = _ref => {
  let {
    options,
    route,
    stackPresentation,
    children,
    internalScreenStyle
  } = _ref;
  const {
    colors
  } = useTheme();
  const {
    headerShown = true,
    contentStyle
  } = options;
  const Screen = React.useContext(ScreenContext);
  const isHeaderInModal = isAndroid ? false : stackPresentation !== 'push' && headerShown === true;
  const headerShownPreviousRef = React.useRef(headerShown);
  React.useEffect(() => {
    warnOnce(!isAndroid && stackPresentation !== 'push' && headerShownPreviousRef.current !== headerShown, `Dynamically changing 'headerShown' in modals will result in remounting the screen and losing all local state. See options for the screen '${route.name}'.`);
    headerShownPreviousRef.current = headerShown;
  }, [headerShown, stackPresentation, route.name]);
  const content = /*#__PURE__*/React.createElement(Container, {
    style: [stackPresentation === 'formSheet' ? Platform.OS === 'ios' ? styles.absoluteFillNoBottom : null : styles.container, stackPresentation !== 'transparentModal' && stackPresentation !== 'containedTransparentModal' && {
      backgroundColor: colors.background
    }, contentStyle]
    // @ts-ignore Wrong props passed to View
    ,
    stackPresentation: stackPresentation
    // This view must *not* be flattened.
    // See https://github.com/software-mansion/react-native-screens/pull/1825
    // for detailed explanation.
    ,
    collapsable: false
  }, children);
  const dimensions = useSafeAreaFrame();
  const topInset = useSafeAreaInsets().top;
  const isStatusBarTranslucent = options.statusBarTranslucent ?? false;
  const statusBarHeight = getStatusBarHeight(topInset, dimensions, isStatusBarTranslucent);
  const hasLargeHeader = options.headerLargeTitle ?? false;
  const headerHeight = getDefaultHeaderHeight(dimensions, statusBarHeight, stackPresentation, hasLargeHeader);
  if (isHeaderInModal) {
    return /*#__PURE__*/React.createElement(ScreenStack, {
      style: styles.container
    }, /*#__PURE__*/React.createElement(Screen, {
      enabled: true,
      isNativeStack: true,
      hasLargeHeader: hasLargeHeader,
      style: [StyleSheet.absoluteFill, internalScreenStyle]
    }, /*#__PURE__*/React.createElement(HeaderHeightContext.Provider, {
      value: headerHeight
    }, /*#__PURE__*/React.createElement(HeaderConfig, _extends({}, options, {
      route: route
    })), content)));
  }
  return content;
};
const RouteView = _ref2 => {
  let {
    descriptors,
    route,
    index,
    navigation,
    stateKey,
    screensRefs
  } = _ref2;
  const {
    options,
    render: renderScene
  } = descriptors[route.key];
  const {
    fullScreenSwipeShadowEnabled = true,
    gestureEnabled,
    headerShown,
    hideKeyboardOnSwipe,
    homeIndicatorHidden,
    sheetLargestUndimmedDetentIndex = 'none',
    sheetGrabberVisible = false,
    sheetCornerRadius = -1.0,
    sheetElevation = 24,
    sheetExpandsWhenScrolledToEdge = true,
    sheetInitialDetentIndex = 0,
    nativeBackButtonDismissalEnabled = false,
    navigationBarColor,
    navigationBarTranslucent,
    navigationBarHidden,
    replaceAnimation = 'pop',
    screenOrientation,
    statusBarAnimation,
    statusBarColor,
    statusBarHidden,
    statusBarStyle,
    statusBarTranslucent,
    swipeDirection = 'horizontal',
    transitionDuration,
    freezeOnBlur,
    unstable_sheetFooter = null,
    contentStyle
  } = options;
  let {
    sheetAllowedDetents = [1.0],
    customAnimationOnSwipe,
    fullScreenSwipeEnabled,
    gestureResponseDistance,
    stackAnimation,
    stackPresentation = 'push'
  } = options;

  // We take backgroundColor from contentStyle and apply it on Screen.
  // This allows to workaround one issue with truncated
  // content with formSheet presentation.
  let internalScreenStyle;
  if (stackPresentation === 'formSheet' && contentStyle) {
    const flattenContentStyles = StyleSheet.flatten(contentStyle);
    internalScreenStyle = {
      backgroundColor: flattenContentStyles?.backgroundColor
    };
  }
  if (sheetAllowedDetents === 'fitToContents') {
    sheetAllowedDetents = [-1];
  }
  if (swipeDirection === 'vertical') {
    // for `vertical` direction to work, we need to set `fullScreenSwipeEnabled` to `true`
    // so the screen can be dismissed from any point on screen.
    // `customAnimationOnSwipe` needs to be set to `true` so the `stackAnimation` set by user can be used,
    // otherwise `simple_push` will be used.
    // Also, the default animation for this direction seems to be `slide_from_bottom`.
    if (fullScreenSwipeEnabled === undefined) {
      fullScreenSwipeEnabled = true;
    }
    if (customAnimationOnSwipe === undefined) {
      customAnimationOnSwipe = true;
    }
    if (stackAnimation === undefined) {
      stackAnimation = 'slide_from_bottom';
    }
  }
  if (index === 0) {
    // first screen should always be treated as `push`, it resolves problems with no header animation
    // for navigator with first screen as `modal` and the next as `push`
    stackPresentation = 'push';
  }
  const dimensions = useSafeAreaFrame();
  const topInset = useSafeAreaInsets().top;
  const isStatusBarTranslucent = options.statusBarTranslucent ?? false;
  const statusBarHeight = getStatusBarHeight(topInset, dimensions, isStatusBarTranslucent);
  const hasLargeHeader = options.headerLargeTitle ?? false;
  const defaultHeaderHeight = getDefaultHeaderHeight(dimensions, statusBarHeight, stackPresentation, hasLargeHeader);
  const parentHeaderHeight = React.useContext(HeaderHeightContext);
  const isHeaderInPush = isAndroid ? headerShown : stackPresentation === 'push' && headerShown !== false;
  const staticHeaderHeight = isHeaderInPush !== false ? defaultHeaderHeight : parentHeaderHeight ?? 0;

  // We need to ensure the first retrieved header height will be cached and set in animatedHeaderHeight.
  // We're caching the header height here, as on iOS native side events are not always coming to the JS on first notify.
  // TODO: Check why first event is not being received once it is cached on the native side.
  const cachedAnimatedHeaderHeight = React.useRef(defaultHeaderHeight);
  const animatedHeaderHeight = React.useRef(new Animated.Value(staticHeaderHeight, {
    useNativeDriver: true
  })).current;
  const Screen = React.useContext(ScreenContext);
  const {
    dark
  } = useTheme();
  const screenRef = React.useRef(null);
  React.useEffect(() => {
    screensRefs.current[route.key] = screenRef;
    return () => {
      // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
      delete screensRefs.current[route.key];
    };
  });
  return /*#__PURE__*/React.createElement(Screen, {
    key: route.key,
    ref: screenRef,
    enabled: true,
    isNativeStack: true,
    hasLargeHeader: hasLargeHeader,
    style: [StyleSheet.absoluteFill, internalScreenStyle],
    sheetAllowedDetents: sheetAllowedDetents,
    sheetLargestUndimmedDetentIndex: sheetLargestUndimmedDetentIndex,
    sheetGrabberVisible: sheetGrabberVisible,
    sheetInitialDetentIndex: sheetInitialDetentIndex,
    sheetCornerRadius: sheetCornerRadius,
    sheetElevation: sheetElevation,
    sheetExpandsWhenScrolledToEdge: sheetExpandsWhenScrolledToEdge,
    customAnimationOnSwipe: customAnimationOnSwipe,
    freezeOnBlur: freezeOnBlur,
    fullScreenSwipeEnabled: fullScreenSwipeEnabled,
    fullScreenSwipeShadowEnabled: fullScreenSwipeShadowEnabled,
    hideKeyboardOnSwipe: hideKeyboardOnSwipe,
    homeIndicatorHidden: homeIndicatorHidden,
    gestureEnabled: isAndroid ? false : gestureEnabled,
    gestureResponseDistance: gestureResponseDistance,
    nativeBackButtonDismissalEnabled: nativeBackButtonDismissalEnabled,
    navigationBarColor: navigationBarColor,
    navigationBarTranslucent: navigationBarTranslucent,
    navigationBarHidden: navigationBarHidden,
    replaceAnimation: replaceAnimation,
    screenOrientation: screenOrientation,
    stackAnimation: stackAnimation,
    stackPresentation: stackPresentation,
    statusBarAnimation: statusBarAnimation,
    statusBarColor: statusBarColor,
    statusBarHidden: statusBarHidden,
    statusBarStyle: statusBarStyle ?? (dark ? 'light' : 'dark'),
    statusBarTranslucent: statusBarTranslucent,
    swipeDirection: swipeDirection,
    transitionDuration: transitionDuration,
    onHeaderBackButtonClicked: () => {
      navigation.dispatch({
        ...StackActions.pop(),
        source: route.key,
        target: stateKey
      });
    },
    onWillAppear: () => {
      navigation.emit({
        type: 'transitionStart',
        data: {
          closing: false
        },
        target: route.key
      });
    },
    onWillDisappear: () => {
      navigation.emit({
        type: 'transitionStart',
        data: {
          closing: true
        },
        target: route.key
      });
    },
    onAppear: () => {
      navigation.emit({
        type: 'appear',
        target: route.key
      });
      navigation.emit({
        type: 'transitionEnd',
        data: {
          closing: false
        },
        target: route.key
      });
    },
    onDisappear: () => {
      navigation.emit({
        type: 'transitionEnd',
        data: {
          closing: true
        },
        target: route.key
      });
    },
    onHeaderHeightChange: e => {
      const headerHeight = e.nativeEvent.headerHeight;
      if (cachedAnimatedHeaderHeight.current !== headerHeight) {
        // Currently, we're setting value by Animated#setValue, because we want to cache animated value.
        // Also, in React Native 0.72 there was a bug on Fabric causing a large delay between the screen transition,
        // which should not occur.
        // TODO: Check if it's possible to replace animated#setValue to Animated#event.
        animatedHeaderHeight.setValue(headerHeight);
        cachedAnimatedHeaderHeight.current = headerHeight;
      }
    },
    onDismissed: e => {
      navigation.emit({
        type: 'dismiss',
        target: route.key
      });
      const dismissCount = e.nativeEvent.dismissCount > 0 ? e.nativeEvent.dismissCount : 1;
      navigation.dispatch({
        ...StackActions.pop(dismissCount),
        source: route.key,
        target: stateKey
      });
    },
    onSheetDetentChanged: e => {
      navigation.emit({
        type: 'sheetDetentChange',
        target: route.key,
        data: {
          index: e.nativeEvent.index,
          isStable: e.nativeEvent.isStable
        }
      });
    },
    onGestureCancel: () => {
      navigation.emit({
        type: 'gestureCancel',
        target: route.key
      });
    }
  }, /*#__PURE__*/React.createElement(AnimatedHeaderHeightContext.Provider, {
    value: animatedHeaderHeight
  }, /*#__PURE__*/React.createElement(HeaderHeightContext.Provider, {
    value: staticHeaderHeight
  }, /*#__PURE__*/React.createElement(MaybeNestedStack, {
    options: options,
    route: route,
    stackPresentation: stackPresentation,
    internalScreenStyle: internalScreenStyle
  }, renderScene()), /*#__PURE__*/React.createElement(HeaderConfig, _extends({}, options, {
    route: route,
    headerShown: isHeaderInPush
  })), stackPresentation === 'formSheet' && unstable_sheetFooter && /*#__PURE__*/React.createElement(FooterComponent, null, unstable_sheetFooter()))));
};
function NativeStackViewInner(_ref3) {
  let {
    state,
    navigation,
    descriptors
  } = _ref3;
  const {
    key,
    routes
  } = state;
  const currentRouteKey = routes[state.index].key;
  const {
    goBackGesture,
    transitionAnimation,
    screenEdgeGesture
  } = descriptors[currentRouteKey].options;
  const screensRefs = React.useRef({});
  return /*#__PURE__*/React.createElement(ScreenStack, {
    style: styles.container,
    goBackGesture: goBackGesture,
    transitionAnimation: transitionAnimation,
    screenEdgeGesture: screenEdgeGesture ?? false,
    screensRefs: screensRefs,
    currentScreenId: currentRouteKey
  }, routes.map((route, index) => /*#__PURE__*/React.createElement(RouteView, {
    key: route.key,
    descriptors: descriptors,
    route: route,
    index: index,
    navigation: navigation,
    stateKey: key,
    screensRefs: screensRefs
  })));
}
export default function NativeStackView(props) {
  return /*#__PURE__*/React.createElement(SafeAreaProviderCompat, null, /*#__PURE__*/React.createElement(NativeStackViewInner, props));
}
const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  absoluteFill: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0
  },
  absoluteFillNoBottom: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0
  }
});
//# sourceMappingURL=NativeStackView.js.map