"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const components_1 = require("@bluebase/components");
const MainNavigatorContext_1 = require("../MainNavigatorContext");
const core_1 = require("@bluebase/core");
const react_1 = tslib_1.__importStar(require("react"));
const react_router_1 = require("react-router");
const helpers_1 = require("../../helpers");
const lodash_get_1 = tslib_1.__importDefault(require("lodash.get"));
const navigators_1 = require("../../navigators");
const insertChildNavigator_1 = require("../../helpers/insertChildNavigator");
exports.NavigatorInternal = (_a) => {
    var { standalone } = _a, props = tslib_1.__rest(_a, ["standalone"]);
    const ScreenView = core_1.useComponent('ScreenView');
    const screenProps = helpers_1.useScreenProps();
    const { navigator } = react_1.useContext(MainNavigatorContext_1.MainNavigatorContext);
    // eslint-disable-next-line react/prop-types
    const { type, initialRouteName, routes } = props, rest = tslib_1.__rest(props, ["type", "initialRouteName", "routes"]);
    const NavigatorImpl = navigators_1.getNavigator(type);
    if (!NavigatorImpl) {
        return null;
    }
    // If routes is a thunk, resolve it
    const resolvedRoutes = core_1.resolveThunk(routes, screenProps) || [];
    /**
     * Render each indivitual route
     * @param route
     */
    const renderRoute = (route) => {
        const { exact, name, path } = route;
        return (react_1.default.createElement(react_router_1.Route, { key: name, exact: exact, path: path }, (routerProps) => {
            const navigation = helpers_1.historyToActionObject(routerProps, navigator);
            return (react_1.default.createElement(core_1.NavigationContext.Provider, { value: navigation },
                react_1.default.createElement(ScreenView, { Layout: NavigatorImpl.Screen, navigator: props, route: route, navigation: navigation, options: helpers_1.resolveRouteOptions(route, props, navigator, {
                        navigation,
                        screenProps,
                        route: Object.assign(Object.assign({}, route), { params: navigation.state.params }),
                    }) }, route.navigator ? react_1.default.createElement(exports.Navigator, Object.assign({}, route.navigator, { standalone: false })) : null)));
        }));
    };
    /**
     * Redirects to the initial route, if non is given redirects to the
     * first route in the routes array.
     */
    const renderInitialRoute = () => {
        if (resolvedRoutes.length === 0) {
            return null;
        }
        return (react_1.default.createElement(react_router_1.Route, null, (routerProps) => {
            const navigation = helpers_1.historyToActionObject(routerProps, navigator);
            return (react_1.default.createElement(core_1.NavigationContext.Provider, { value: navigation },
                react_1.default.createElement(components_1.Redirect, { routeName: initialRouteName || resolvedRoutes[0].name, params: navigation.state.params })));
        }));
    };
    return (react_1.default.createElement(NavigatorImpl.Navigator, Object.assign({}, props, { routes: resolvedRoutes }),
        react_1.default.createElement(react_router_1.Switch, Object.assign({}, rest),
            resolvedRoutes.map(renderRoute),
            renderInitialRoute())));
};
exports.NavigatorInternal.displayName = 'NavigatorInternal';
exports.Navigator = (_a) => {
    var { standalone, standaloneLocationRouteName } = _a, inputProps = tslib_1.__rest(_a, ["standalone", "standaloneLocationRouteName"]);
    // If navigator is not standalone, we don't need to do anything special
    if (!standalone) {
        return react_1.default.createElement(exports.NavigatorInternal, Object.assign({}, inputProps, { standalone: false }));
    }
    const { state } = core_1.useNavigation();
    // Extract parent navigator/routes
    const { navigator: mainNavigator } = react_1.useContext(MainNavigatorContext_1.MainNavigatorContext);
    // Merge standalone navigator into parent
    const newNav = insertChildNavigator_1.insertChildNavigator(mainNavigator, inputProps, state.routeName);
    // Prepare paths
    const navigatorObject = helpers_1.preparePaths(newNav);
    // Find processed standalone navigator
    const routeObj = helpers_1.findRouteByKey(state.routeName, 'name', navigatorObject);
    const key = lodash_get_1.default(routeObj, 'navigator.routes', [])
        .map((r) => r.name)
        .join(',');
    // Need to re-create main navigation context with new merged configs
    return (react_1.default.createElement(MainNavigatorContext_1.MainNavigatorContextProvider, { key: key, value: navigatorObject },
        react_1.default.createElement(react_router_1.Route, null, (routerProps) => {
            // Need to re-create navigation context with new merged configs
            const navigation = helpers_1.historyToActionObject(routerProps, navigatorObject);
            return (react_1.default.createElement(core_1.NavigationContext.Provider, { value: navigation },
                react_1.default.createElement(exports.NavigatorInternal, Object.assign({}, lodash_get_1.default(routeObj, 'navigator', {}), { standalone: false }))));
        })));
};
exports.Navigator.displayName = 'Navigator';
exports.Navigator.displayProps = {
    standalone: true,
};
