"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@bluebase/core");
const components_1 = require("@bluebase/components");
const lib_1 = require("../../lib");
const react_1 = tslib_1.__importDefault(require("react"));
const historyToActionObject_1 = require("../../helpers/historyToActionObject");
const renderNavigator_1 = require("../../helpers/renderNavigator");
/**
 * Base Navigator
 *
 * Contain functionality common to all Navigators
 */
class BaseNavigator extends react_1.default.Component {
    constructor() {
        super(...arguments);
        this.state = {
            routes: this.props.routes || [],
        };
    }
    /**
     * We resolve all screen components here
     * @param props
     */
    static getDerivedStateFromProps(props) {
        const routes = (props.routes || []).map(route => {
            // If there is no screen component, render nothing
            if (!route.screen) {
                return route;
            }
            return Object.assign({}, route, { 
                // If screen prop is a string resolve that component from BlueBase, otherwisen use as is
                screen: (typeof route.screen === 'string') ? core_1.getComponent(route.screen) : route.screen });
        });
        return { routes };
    }
    render() {
        const BB = this.context;
        const _a = this.props, { type, initialRouteName } = _a, rest = tslib_1.__rest(_a, ["type", "initialRouteName"]);
        const { routes } = this.state;
        if (routes.length === 0) {
            return null;
        }
        const initialRoute = initialRouteName || routes[0].name;
        return (react_1.default.createElement(lib_1.Switch, Object.assign({}, rest),
            routes.map(route => this.renderRoute(route, BB)),
            !!initialRoute ? react_1.default.createElement(components_1.Redirect, { routeName: initialRoute }) : null));
    }
    /**
     * Render each indivitual route
     * @param route
     * @param BB
     */
    renderRoute(route, BB) {
        const { exact, name, navigationOptions, navigator, path, screen } = route;
        const RouteView = this.props.RouteView || screen || components_1.Noop;
        const finalNavigationOptions = (navigation) => (screen && screen.navigationOptions !== undefined) ? Object.assign({}, navigationOptions, core_1.resolveThunk(screen.navigationOptions, { navigation })) : Object.assign({}, navigationOptions);
        return (react_1.default.createElement(lib_1.Route, { key: name, exact: exact, path: path }, (routerProps) => {
            const navigation = historyToActionObject_1.historyToActionObject(routerProps, BB);
            return (react_1.default.createElement(RouteView, { screen: screen, navigation: navigation, navigationOptions: finalNavigationOptions(navigation), navigator: this.props }, navigator && renderNavigator_1.renderNavigator(navigator, BB)));
        }));
    }
}
BaseNavigator.contextType = core_1.BlueBaseContext;
exports.BaseNavigator = BaseNavigator;
