import { Agent, ConsoleLogger, HttpOutboundTransport, LogLevel, WsOutboundTransport } from '@aries-framework/core';
import { useAgent } from '@aries-framework/react-hooks';
import { agentDependencies } from '@aries-framework/react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useNavigation } from '@react-navigation/core';
import { CommonActions } from '@react-navigation/native';
import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { DeviceEventEmitter, StyleSheet } from 'react-native';
import { Config } from 'react-native-config';
import { SafeAreaView } from 'react-native-safe-area-context';
import { EventTypes, LocalStorageKeys } from '../constants';
import { useAnimatedComponents } from '../contexts/animated-components';
import { useAuth } from '../contexts/auth';
import { useConfiguration } from '../contexts/configuration';
import { DispatchAction } from '../contexts/reducers/store';
import { useStore } from '../contexts/store';
import { useTheme } from '../contexts/theme';
import { loadLoginAttempt } from '../services/keychain';
import { BifoldError } from '../types/error';
import { Screens, Stacks } from '../types/navigators';
import { getAgentModules, createLinkSecretIfRequired } from '../utils/agent';
import { migrateToAskar, didMigrateToAskar } from '../utils/migration';
const onboardingComplete = state => {
  return state.didCompleteTutorial && state.didAgreeToTerms && state.didCreatePIN && state.didConsiderBiometry;
};
const resumeOnboardingAt = (state, enableWalletNaming, showPreface) => {
  if ((state.didSeePreface || !showPreface) && state.didCompleteTutorial && state.didAgreeToTerms && state.didCreatePIN && (state.didNameWallet || !enableWalletNaming) && !state.didConsiderBiometry) {
    return Screens.UseBiometry;
  }
  if ((state.didSeePreface || !showPreface) && state.didCompleteTutorial && state.didAgreeToTerms && state.didCreatePIN && enableWalletNaming && !state.didNameWallet) {
    return Screens.NameWallet;
  }
  if ((state.didSeePreface || !showPreface) && state.didCompleteTutorial && state.didAgreeToTerms && !state.didCreatePIN) {
    return Screens.CreatePIN;
  }
  if ((state.didSeePreface || !showPreface) && state.didCompleteTutorial && !state.didAgreeToTerms) {
    return Screens.Terms;
  }
  if (state.didSeePreface || !showPreface) {
    return Screens.Onboarding;
  }
  return Screens.Preface;
};

/**
 * To customize this splash screen set the background color of the
 * iOS and Android launch screen to match the background color of
 * of this view.
 */
const Splash = () => {
  const {
    indyLedgers,
    showPreface
  } = useConfiguration();
  const {
    setAgent
  } = useAgent();
  const {
    t
  } = useTranslation();
  const [store, dispatch] = useStore();
  const navigation = useNavigation();
  const {
    getWalletCredentials
  } = useAuth();
  const {
    ColorPallet
  } = useTheme();
  const {
    LoadingIndicator
  } = useAnimatedComponents();
  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: ColorPallet.brand.primaryBackground
    }
  });
  const loadAuthAttempts = async () => {
    const attempts = await loadLoginAttempt();
    if (attempts) {
      dispatch({
        type: DispatchAction.ATTEMPT_UPDATED,
        payload: [attempts]
      });
      return attempts;
    }
  };
  useEffect(() => {
    if (store.authentication.didAuthenticate) {
      return;
    }
    const initOnboarding = async () => {
      try {
        // load authentication attempts from storage
        const attemptData = await loadAuthAttempts();
        const preferencesData = await AsyncStorage.getItem(LocalStorageKeys.Preferences);
        if (preferencesData) {
          const dataAsJSON = JSON.parse(preferencesData);
          dispatch({
            type: DispatchAction.PREFERENCES_UPDATED,
            payload: [dataAsJSON]
          });
        }
        const migrationData = await AsyncStorage.getItem(LocalStorageKeys.Migration);
        if (migrationData) {
          const dataAsJSON = JSON.parse(migrationData);
          dispatch({
            type: DispatchAction.MIGRATION_UPDATED,
            payload: [dataAsJSON]
          });
        }
        const toursData = await AsyncStorage.getItem(LocalStorageKeys.Tours);
        if (toursData) {
          const dataAsJSON = JSON.parse(toursData);
          dispatch({
            type: DispatchAction.TOUR_DATA_UPDATED,
            payload: [dataAsJSON]
          });
        }
        const data = await AsyncStorage.getItem(LocalStorageKeys.Onboarding);
        if (data) {
          const onboardingState = JSON.parse(data);
          dispatch({
            type: DispatchAction.ONBOARDING_UPDATED,
            payload: [onboardingState]
          });
          if (onboardingComplete(onboardingState)) {
            // if they previously completed onboarding before wallet naming was enabled, mark complete
            if (!store.onboarding.didNameWallet) {
              dispatch({
                type: DispatchAction.DID_NAME_WALLET,
                payload: [true]
              });
            }

            // if they previously completed onboarding before preface was enabled, mark seen
            if (!store.onboarding.didSeePreface) {
              dispatch({
                type: DispatchAction.DID_SEE_PREFACE
              });
            }
            if (!(attemptData !== null && attemptData !== void 0 && attemptData.lockoutDate)) {
              navigation.dispatch(CommonActions.reset({
                index: 0,
                routes: [{
                  name: Screens.EnterPIN
                }]
              }));
            } else {
              // return to lockout screen if lockout date is set
              navigation.dispatch(CommonActions.reset({
                index: 0,
                routes: [{
                  name: Screens.AttemptLockout
                }]
              }));
            }
            return;
          } else {
            // If onboarding was interrupted we need to pickup from where we left off.
            navigation.dispatch(CommonActions.reset({
              index: 0,
              routes: [{
                name: resumeOnboardingAt(onboardingState, store.preferences.enableWalletNaming, showPreface)
              }]
            }));
          }
          return;
        }
        // We have no onboarding state, starting from step zero.
        if (showPreface) {
          navigation.dispatch(CommonActions.reset({
            index: 0,
            routes: [{
              name: Screens.Preface
            }]
          }));
        } else {
          navigation.dispatch(CommonActions.reset({
            index: 0,
            routes: [{
              name: Screens.Onboarding
            }]
          }));
        }
      } catch (err) {
        const error = new BifoldError(t('Error.Title1044'), t('Error.Message1044'), (err === null || err === void 0 ? void 0 : err.message) ?? err, 1044);
        DeviceEventEmitter.emit(EventTypes.ERROR_ADDED, error);
      }
    };
    initOnboarding();
  }, [store.authentication.didAuthenticate]);
  useEffect(() => {
    if (!store.authentication.didAuthenticate || !store.onboarding.didConsiderBiometry) {
      return;
    }
    const initAgent = async () => {
      try {
        const credentials = await getWalletCredentials();
        if (!(credentials !== null && credentials !== void 0 && credentials.id) || !credentials.key) {
          // Cannot find wallet id/secret
          return;
        }
        const newAgent = new Agent({
          config: {
            label: store.preferences.walletName || 'Aries Bifold',
            walletConfig: {
              id: credentials.id,
              key: credentials.key
            },
            logger: new ConsoleLogger(LogLevel.trace),
            autoUpdateStorageOnStartup: true
          },
          dependencies: agentDependencies,
          modules: getAgentModules({
            indyNetworks: indyLedgers,
            mediatorInvitationUrl: Config.MEDIATOR_URL
          })
        });
        const wsTransport = new WsOutboundTransport();
        const httpTransport = new HttpOutboundTransport();
        newAgent.registerOutboundTransport(wsTransport);
        newAgent.registerOutboundTransport(httpTransport);

        // If we haven't migrated to Aries Askar yet, we need to do this before we initialize the agent.
        if (!didMigrateToAskar(store.migration)) {
          newAgent.config.logger.debug('Agent not updated to Aries Askar, updating...');
          await migrateToAskar(credentials.id, credentials.key, newAgent);
          newAgent.config.logger.debug('Successfully finished updating agent to Aries Askar');
          // Store that we migrated to askar.
          dispatch({
            type: DispatchAction.DID_MIGRATE_TO_ASKAR
          });
        }
        await newAgent.initialize();
        await createLinkSecretIfRequired(newAgent);
        setAgent(newAgent);
        navigation.dispatch(CommonActions.reset({
          index: 0,
          routes: [{
            name: Stacks.TabStack
          }]
        }));
      } catch (err) {
        const error = new BifoldError(t('Error.Title1045'), t('Error.Message1045'), (err === null || err === void 0 ? void 0 : err.message) ?? err, 1045);
        DeviceEventEmitter.emit(EventTypes.ERROR_ADDED, error);
      }
    };
    initAgent();
  }, [store.authentication.didAuthenticate, store.onboarding.didConsiderBiometry]);
  return /*#__PURE__*/React.createElement(SafeAreaView, {
    style: styles.container
  }, /*#__PURE__*/React.createElement(LoadingIndicator, null));
};
export default Splash;
//# sourceMappingURL=Splash.js.map