import React, { PureComponent } from 'react';
import { StackActions, NavigationActions } from 'react-navigation';
import { NativeNavigatorModes } from './types';
import NativeStackNavigator from './NativeStackNavigator';
import NativeScenes from './NativeScenes';
export default class NativeNavigators extends PureComponent {
    constructor() {
        super(...arguments);
        this.state = {
            propRoutes: [],
            routes: [],
            closingRouteKey: null,
            descriptors: {},
            screenProps: undefined
        };
        this.handleOpenRoute = (route) => {
            this.handleTransitionComplete(route);
        };
        this.handleCloseRoute = (route) => {
            this.handleTransitionComplete(route);
            this.setState({
                closingRouteKey: null,
                routes: this.state.routes.filter(r => r.key !== route.key)
            });
        };
        this.handleTransitionComplete = (route) => {
            const { navigation } = this.props;
            if (navigation.state.isTransitioning) {
                navigation.dispatch(StackActions.completeTransition({ toChildKey: route.key }));
            }
        };
        this.handleDismissRoute = (route) => {
            const { navigation } = this.props;
            const { routes, propRoutes } = this.state;
            this.setState({
                routes: routes.filter(r => r.key !== route.key),
                propRoutes: propRoutes.filter(r => r.key !== route.key)
            });
            navigation.dispatch({
                type: NavigationActions.BACK,
                key: route.key,
                immediate: true
            });
        };
    }
    static getDerivedStateFromProps(props, state) {
        var _a;
        const { navigation, screenProps } = props;
        if (navigation.state.routes === state.propRoutes && screenProps === state.screenProps && state.routes.length) {
            return null;
        }
        let routes = navigation.state.index < navigation.state.routes.length - 1
            ? // Remove any extra routes from the state
                // The last visible route should be the focused route, i.e. at current index
                navigation.state.routes.slice(0, navigation.state.index + 1)
            : navigation.state.routes;
        const routeKeys = routes.map(route => route.key);
        let { closingRouteKey } = state;
        const previousFocusedRoute = state.routes[state.routes.length - 1];
        const nextFocusedRoute = routes[routes.length - 1];
        if (closingRouteKey === ((_a = previousFocusedRoute) === null || _a === void 0 ? void 0 : _a.key)) {
            // During a closing transition, just update the routes state.
            routes = [...routes, previousFocusedRoute];
        }
        else if (previousFocusedRoute &&
            previousFocusedRoute.key !== nextFocusedRoute.key) {
            // Should perform a closing transition, and keep the topmost scene in the routes state.
            if (!routeKeys.includes(previousFocusedRoute.key)) {
                routes = [...routes, previousFocusedRoute];
                closingRouteKey = previousFocusedRoute.key;
            }
        }
        const descriptors = routes.reduce((acc, route) => {
            acc[route.key] =
                props.descriptors[route.key] || state.descriptors[route.key];
            return acc;
        }, {});
        return {
            descriptors,
            closingRouteKey,
            routes,
            propRoutes: navigation.state.routes,
            screenProps
        };
    }
    render() {
        const { navigation, navigationConfig } = this.props;
        const { closingRouteKey, routes, descriptors, screenProps } = this.state;
        const mode = navigationConfig.mode || NativeNavigatorModes.Modal;
        return (<NativeStackNavigator mode={mode}>
        <NativeScenes mode={mode} headerMode={navigationConfig.headerMode} routes={routes} descriptors={descriptors} navigation={navigation} screenProps={screenProps} onOpenRoute={this.handleOpenRoute} onCloseRoute={this.handleCloseRoute} onDismissRoute={this.handleDismissRoute} closingRouteKey={closingRouteKey}/>
      </NativeStackNavigator>);
    }
}
//# sourceMappingURL=NativeNavigators.js.map