"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _core = require("@aries-framework/core");
var _reactHooks = require("@aries-framework/react-hooks");
var _ariesBifoldVerifier = require("@hyperledger/aries-bifold-verifier");
var _core2 = require("@react-navigation/core");
var _stack = require("@react-navigation/stack");
var _queryString = require("query-string");
var _react = _interopRequireWildcard(require("react"));
var _reactI18next = require("react-i18next");
var _reactNative = require("react-native");
var _HeaderButton = _interopRequireWildcard(require("../components/buttons/HeaderButton"));
var _constants = require("../constants");
var _auth = require("../contexts/auth");
var _configuration = require("../contexts/configuration");
var _store = require("../contexts/reducers/store");
var _store2 = require("../contexts/store");
var _theme = require("../contexts/theme");
var _deepLinks = require("../hooks/deep-links");
var _AttemptLockout = _interopRequireDefault(require("../screens/AttemptLockout"));
var _Chat = _interopRequireDefault(require("../screens/Chat"));
var _NameWallet = _interopRequireDefault(require("../screens/NameWallet"));
var _Onboarding = _interopRequireDefault(require("../screens/Onboarding"));
var _OnboardingPages = require("../screens/OnboardingPages");
var _PINCreate = _interopRequireDefault(require("../screens/PINCreate"));
var _PINEnter = _interopRequireDefault(require("../screens/PINEnter"));
var _error = require("../types/error");
var _navigators = require("../types/navigators");
var _helpers = require("../utils/helpers");
var _testable = require("../utils/testable");
var _ConnectStack = _interopRequireDefault(require("./ConnectStack"));
var _ContactStack = _interopRequireDefault(require("./ContactStack"));
var _DeliveryStack = _interopRequireDefault(require("./DeliveryStack"));
var _NotificationStack = _interopRequireDefault(require("./NotificationStack"));
var _ProofRequestStack = _interopRequireDefault(require("./ProofRequestStack"));
var _SettingStack = _interopRequireDefault(require("./SettingStack"));
var _TabStack = _interopRequireDefault(require("./TabStack"));
var _defaultStackOptions = require("./defaultStackOptions");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
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); }
const RootStack = () => {
  const [state, dispatch] = (0, _store2.useStore)();
  const {
    removeSavedWalletSecret
  } = (0, _auth.useAuth)();
  const {
    agent
  } = (0, _reactHooks.useAgent)();
  const appState = (0, _react.useRef)(_reactNative.AppState.currentState);
  const [backgroundTime, setBackgroundTime] = (0, _react.useState)(undefined);
  const [prevAppStateVisible, setPrevAppStateVisible] = (0, _react.useState)('');
  const [appStateVisible, setAppStateVisible] = (0, _react.useState)('');
  const {
    t
  } = (0, _reactI18next.useTranslation)();
  const navigation = (0, _core2.useNavigation)();
  const theme = (0, _theme.useTheme)();
  const defaultStackOptions = (0, _defaultStackOptions.createDefaultStackOptions)(theme);
  const OnboardingTheme = theme.OnboardingTheme;
  const {
    pages,
    terms,
    splash,
    useBiometry,
    developer,
    preface,
    showPreface,
    enableImplicitInvitations,
    enableReuseConnections,
    disableOnboardingSkip
  } = (0, _configuration.useConfiguration)();
  (0, _deepLinks.useDeepLinks)();

  // remove connection on mobile verifier proofs if proof is rejected regardless of if it has been opened
  const declinedProofs = (0, _reactHooks.useProofByState)([_core.ProofState.Declined, _core.ProofState.Abandoned]);
  (0, _react.useEffect)(() => {
    declinedProofs.forEach(proof => {
      var _proof$metadata;
      const meta = proof === null || proof === void 0 ? void 0 : (_proof$metadata = proof.metadata) === null || _proof$metadata === void 0 ? void 0 : _proof$metadata.get(_ariesBifoldVerifier.ProofMetadata.customMetadata);
      if (meta !== null && meta !== void 0 && meta.delete_conn_after_seen) {
        agent === null || agent === void 0 ? void 0 : agent.connections.deleteById((proof === null || proof === void 0 ? void 0 : proof.connectionId) ?? '').catch(() => {});
        proof === null || proof === void 0 ? void 0 : proof.metadata.set(_ariesBifoldVerifier.ProofMetadata.customMetadata, {
          ...meta,
          delete_conn_after_seen: false
        });
      }
    });
  }, [declinedProofs, state.preferences.useDataRetention]);
  const lockoutUser = async () => {
    if (agent && state.authentication.didAuthenticate) {
      // make sure agent is shutdown so wallet isn't still open
      removeSavedWalletSecret();
      await agent.wallet.close();
      await agent.shutdown();
      dispatch({
        type: _store.DispatchAction.DID_AUTHENTICATE,
        payload: [{
          didAuthenticate: false
        }]
      });
      dispatch({
        type: _store.DispatchAction.LOCKOUT_UPDATED,
        payload: [{
          displayNotification: true
        }]
      });
    }
  };

  // handle deeplink events
  (0, _react.useEffect)(() => {
    async function handleDeepLink(deepLink) {
      // If it's just the general link with no params, set link inactive and do nothing
      if (deepLink.endsWith('//')) {
        dispatch({
          type: _store.DispatchAction.ACTIVE_DEEP_LINK,
          payload: [undefined]
        });
        return;
      }
      try {
        var _receivedInvitation$c;
        // Try connection based
        const receivedInvitation = await (0, _helpers.connectFromInvitation)(deepLink, agent, enableImplicitInvitations, enableReuseConnections);
        navigation.navigate(_navigators.Stacks.ConnectionStack, {
          screen: _navigators.Screens.Connection,
          params: {
            connectionId: receivedInvitation === null || receivedInvitation === void 0 ? void 0 : (_receivedInvitation$c = receivedInvitation.connectionRecord) === null || _receivedInvitation$c === void 0 ? void 0 : _receivedInvitation$c.id
          }
        });
      } catch {
        try {
          // Try connectionless here
          const queryParams = (0, _queryString.parseUrl)(deepLink).query;
          const param = queryParams['d_m'] ?? queryParams['c_i'];
          // if missing both of the required params, don't attempt to open OOB
          if (!param) {
            dispatch({
              type: _store.DispatchAction.ACTIVE_DEEP_LINK,
              payload: [undefined]
            });
            return;
          }
          const message = await (0, _helpers.getOobDeepLink)(deepLink, agent);
          navigation.navigate(_navigators.Stacks.ConnectionStack, {
            screen: _navigators.Screens.Connection,
            params: {
              threadId: message['@id']
            }
          });
        } catch (err) {
          const error = new _error.BifoldError(t('Error.Title1039'), t('Error.Message1039'), (err === null || err === void 0 ? void 0 : err.message) ?? err, 1039);
          _reactNative.DeviceEventEmitter.emit(_constants.EventTypes.ERROR_ADDED, error);
        }
      }

      // set deeplink as inactive
      dispatch({
        type: _store.DispatchAction.ACTIVE_DEEP_LINK,
        payload: [undefined]
      });
    }
    if (agent && state.deepLink.activeDeepLink && state.authentication.didAuthenticate) {
      handleDeepLink(state.deepLink.activeDeepLink);
    }
  }, [agent, state.deepLink.activeDeepLink, state.authentication.didAuthenticate]);
  (0, _react.useEffect)(() => {
    _reactNative.AppState.addEventListener('change', nextAppState => {
      if (appState.current.match(/active/) && nextAppState.match(/inactive|background/)) {
        //update time that app gets put in background
        setBackgroundTime(Date.now());
      }
      setPrevAppStateVisible(appState.current);
      appState.current = nextAppState;
      setAppStateVisible(appState.current);
    });
  }, []);
  (0, _react.useEffect)(() => {
    if (appStateVisible.match(/active/) && prevAppStateVisible.match(/inactive|background/) && backgroundTime) {
      // prevents the user from being locked out during metro reloading
      setPrevAppStateVisible(appStateVisible);
      //lock user out after 5 minutes
      if (!state.preferences.preventAutoLock && _constants.walletTimeout && backgroundTime && Date.now() - backgroundTime > _constants.walletTimeout) {
        lockoutUser();
      }
    }
  }, [appStateVisible, prevAppStateVisible, backgroundTime]);
  const onTutorialCompleted = () => {
    dispatch({
      type: _store.DispatchAction.DID_COMPLETE_TUTORIAL
    });
    navigation.navigate(_navigators.Screens.Terms);
  };
  const onAuthenticated = status => {
    if (!status) {
      return;
    }
    dispatch({
      type: _store.DispatchAction.DID_AUTHENTICATE
    });
  };
  const authStack = () => {
    const Stack = (0, _stack.createStackNavigator)();
    return /*#__PURE__*/_react.default.createElement(Stack.Navigator, {
      initialRouteName: _navigators.Screens.Splash,
      screenOptions: {
        ...defaultStackOptions,
        headerShown: false
      }
    }, /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Splash,
      component: splash
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.EnterPIN,
      options: () => ({
        title: t('Screens.EnterPIN'),
        headerShown: true,
        headerLeft: () => false,
        rightLeft: () => false
      })
    }, props => /*#__PURE__*/_react.default.createElement(_PINEnter.default, _extends({}, props, {
      setAuthenticated: onAuthenticated
    }))), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.AttemptLockout,
      component: _AttemptLockout.default,
      options: {
        headerShown: true,
        headerLeft: () => null
      }
    }));
  };
  const mainStack = () => {
    const Stack = (0, _stack.createStackNavigator)();

    // This function is to make the fade in behavior of both iOS and Android consistent for the settings menu
    const forFade = _ref => {
      let {
        current
      } = _ref;
      return {
        cardStyle: {
          opacity: current.progress
        }
      };
    };
    return /*#__PURE__*/_react.default.createElement(Stack.Navigator, {
      initialRouteName: _navigators.Screens.Splash,
      screenOptions: {
        ...defaultStackOptions,
        headerShown: false
      }
    }, /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Splash,
      component: splash
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.TabStack,
      component: _TabStack.default
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Chat,
      component: _Chat.default,
      options: _ref2 => {
        let {
          navigation
        } = _ref2;
        return {
          headerShown: true,
          title: t('Screens.CredentialOffer'),
          headerLeft: () => /*#__PURE__*/_react.default.createElement(_HeaderButton.default, {
            buttonLocation: _HeaderButton.ButtonLocation.Left,
            accessibilityLabel: t('Global.Back'),
            testID: (0, _testable.testIdWithKey)('BackButton'),
            onPress: () => {
              navigation.navigate(_navigators.TabStacks.HomeStack, {
                screen: _navigators.Screens.Home
              });
            },
            icon: "arrow-left"
          })
        };
      }
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.ConnectStack,
      component: _ConnectStack.default
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.SettingStack,
      component: _SettingStack.default,
      options: {
        cardStyleInterpolator: forFade
      }
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.ContactStack,
      component: _ContactStack.default
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.NotificationStack,
      component: _NotificationStack.default
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.ConnectionStack,
      component: _DeliveryStack.default,
      options: {
        gestureEnabled: false
      }
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Stacks.ProofRequestsStack,
      component: _ProofRequestStack.default
    }));
  };
  const onboardingStack = () => {
    const Stack = (0, _stack.createStackNavigator)();
    const carousel = (0, _OnboardingPages.createCarouselStyle)(OnboardingTheme);
    return /*#__PURE__*/_react.default.createElement(Stack.Navigator, {
      initialRouteName: _navigators.Screens.Splash,
      screenOptions: {
        ...defaultStackOptions,
        headerShown: false
      }
    }, /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Splash,
      component: splash
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Preface,
      component: preface,
      options: {
        title: t('Screens.Preface'),
        headerShown: true
      }
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Onboarding,
      options: () => ({
        title: t('Screens.Onboarding'),
        headerTintColor: OnboardingTheme.headerTintColor,
        headerShown: true,
        gestureEnabled: false,
        headerLeft: () => false
      })
    }, props => /*#__PURE__*/_react.default.createElement(_Onboarding.default, _extends({}, props, {
      nextButtonText: t('Global.Next'),
      previousButtonText: t('Global.Back'),
      pages: pages(onTutorialCompleted, OnboardingTheme),
      disableSkip: disableOnboardingSkip,
      style: carousel
    }))), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Terms,
      options: () => ({
        title: t('Screens.Terms'),
        headerTintColor: OnboardingTheme.headerTintColor,
        headerShown: true,
        headerLeft: () => false,
        rightLeft: () => false
      }),
      component: terms
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.CreatePIN,
      options: () => ({
        title: t('Screens.CreatePIN'),
        headerShown: true,
        headerLeft: () => false,
        rightLeft: () => false
      })
    }, props => /*#__PURE__*/_react.default.createElement(_PINCreate.default, _extends({}, props, {
      setAuthenticated: onAuthenticated
    }))), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.NameWallet,
      options: () => ({
        title: t('Screens.NameWallet'),
        headerTintColor: OnboardingTheme.headerTintColor,
        headerShown: true,
        headerLeft: () => false,
        rightLeft: () => false
      }),
      component: _NameWallet.default
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.UseBiometry,
      options: () => ({
        title: t('Screens.Biometry'),
        headerTintColor: OnboardingTheme.headerTintColor,
        headerShown: true,
        headerLeft: () => false,
        rightLeft: () => false
      }),
      component: useBiometry
    }), /*#__PURE__*/_react.default.createElement(Stack.Screen, {
      name: _navigators.Screens.Developer,
      component: developer,
      options: {
        ...defaultStackOptions,
        title: t('Screens.Developer'),
        headerBackTestID: (0, _testable.testIdWithKey)('Back')
      }
    }));
  };
  if ((!showPreface || state.onboarding.didSeePreface) && state.onboarding.didAgreeToTerms && state.onboarding.didCompleteTutorial && state.onboarding.didCreatePIN && (!state.preferences.enableWalletNaming || state.onboarding.didNameWallet) && state.onboarding.didConsiderBiometry) {
    return state.authentication.didAuthenticate ? mainStack() : authStack();
  }
  return onboardingStack();
};
var _default = RootStack;
exports.default = _default;
//# sourceMappingURL=RootStack.js.map