import { __awaiter, __decorate, __param } from "tslib";
import { Container, optional } from '@microsoft/fast-foundation';
import { RouterConfiguration, Route } from '@microsoft/fast-router';
import { Auth, Session, FoundationAnalytics, FoundationAnalyticsEventType, } from '@genesislcap/foundation-comms';
import { defaultLayout } from '../layouts';
import { LoginForm } from './login-form/login-form';
import { ForgotPassword } from './forgot-password/forgot-password';
import { NotFound } from './not-found/not-found';
import { RequestAccount } from './request-account/request-account';
import { Verify } from './verify/verify';
import { Protected } from './protected/protected';
import { ResetPassword } from './reset-password/reset-password';
import { defaultLoginConfig, LoginConfig } from '../main';
/**
 * Base implementation of a routing used with the Login class
 *
 * @remarks
 *
 * Could be used when using the Login class as a standalone authentication method
 * with your app
 *
 * @internal
 */
let MainRouterConfig = class MainRouterConfig extends RouterConfiguration {
    constructor(auth, container, analytics, session, loginConfig = defaultLoginConfig) {
        super();
        this.auth = auth;
        this.container = container;
        this.analytics = analytics;
        this.session = session;
        this.loginConfig = loginConfig;
    }
    configure() {
        this.title = 'Login';
        this.defaultLayout = defaultLayout;
        /**
         * TODO: Cascade the template options to child routes in a subsequent PR
         * element: async () => {
         *    const { define, templateOptions, template, styles } = await import(
         *        /!* webpackChunkName: "login-form" *!/
         *        './login-form'
         *    );
         *    return define(this.compose(templateOptions, template, styles, 'login-form'));
         * },
         */
        const routes = [
            {
                path: '',
                name: 'login',
                element: LoginForm,
                title: 'Login',
                settings: { public: true },
            },
            {
                path: 'not-found',
                element: NotFound,
                title: 'Not Found',
                name: 'not-found',
                settings: { public: true },
            },
        ];
        const { omitRoutes } = this.loginConfig;
        if (!omitRoutes.includes('request-account')) {
            routes.push({
                path: 'request-account',
                name: 'request-account',
                element: RequestAccount,
                title: 'Request Account',
                settings: { public: true },
            });
        }
        if (!omitRoutes.includes('reset-password')) {
            routes.push({
                path: 'reset-password',
                name: 'reset-password',
                element: ResetPassword,
                title: 'Reset Password',
                settings: { public: true },
            });
        }
        if (!omitRoutes.includes('forgot-password')) {
            routes.push({
                path: 'forgot-password',
                name: 'forgot-password',
                element: ForgotPassword,
                title: 'Forgot Password',
                settings: { public: true },
            });
        }
        if (!omitRoutes.includes('verify')) {
            routes.push({
                path: 'verify',
                element: Verify,
                title: 'Verify',
                name: 'verify',
                settings: { public: true },
            });
        }
        if (!omitRoutes.includes('protected')) {
            routes.push({
                path: 'protected',
                element: Protected,
                title: 'Protected',
                name: 'protected',
                settings: { public: false },
            });
        }
        this.routes.map(...routes);
        const session = this.session;
        const auth = this.auth;
        const analytics = this.analytics;
        /**
         * Example of a FallbackRouteDefinition
         */
        this.routes.fallback(() => auth.isLoggedIn ? { redirect: 'not-found' } : { redirect: 'login' });
        /**
         * Example of a NavigationContributor
         */
        this.contributors.push({
            navigate: (phase) => __awaiter(this, void 0, void 0, function* () {
                const settings = phase.route.settings;
                /**
                 * TODO: Centralise
                 * Suspect this should be done via createEventSink, but it's not fully clear how-to do that as no docs
                 */
                analytics.trackEvent(FoundationAnalyticsEventType.routeChanged, {
                    path: phase.route.endpoint.path,
                });
                /**
                 * If public route don't block
                 */
                if (settings && settings.public) {
                    return;
                }
                /**
                 * If logged in don't block
                 */
                if (auth.isLoggedIn) {
                    return;
                }
                /**
                 * If allowAutoAuth and session is valid try to connect+auto-login
                 */
                if (this.loginConfig.autoAuth && (yield auth.reAuthFromSession())) {
                    return;
                }
                /**
                 * Otherwise route them to login
                 */
                phase.cancel(() => {
                    session.captureReturnUrl();
                    Route.name.replace(phase.router, 'login');
                });
            }),
        });
    }
    construct(Type) {
        return this.container.get(Type);
    }
};
MainRouterConfig = __decorate([
    __param(0, Auth),
    __param(1, Container),
    __param(2, FoundationAnalytics),
    __param(3, Session),
    __param(4, optional(LoginConfig))
], MainRouterConfig);
export { MainRouterConfig };
//# sourceMappingURL=config.js.map