import { isNothing, unwrapOptional as unwrap } from "@jet/environment/types/optional";
import { FlowAction } from "../../api/models";
import { generateRoutes } from "../util/generate-routes";
import { updateWebNavigation } from "./inject-web-navigation";
/**
 * Determine if the two {@linkcode LandingPageIntent} arguments are equivalent
 */
export function landingPageIntentsAreEquivalent(activeIntent, navLinkIntent) {
    if (isNothing(activeIntent) || isNothing(navLinkIntent)) {
        return false;
    }
    for (const key of ["$kind", "storefront", "language"]) {
        if (activeIntent[key] !== navLinkIntent[key]) {
            return false;
        }
    }
    return true;
}
/**
 * Dynamically create an {@linkcode IntentController} for a platform "landing page"
 *
 * A "landing page" is a vanity URL within a specific platform that loads some other
 * page under-the-hood; the "canonical URL" for the "landing page" should reflect this
 * vanity URL, rather than the real canonical URL for the underlying Media API entity.
 *
 * @param url the vanity URL for the landing page
 * @param intentFactory a function that produces the underlying `Intent` for the data backing the landing page
 * @param prepareAction a function that can be used to provide additional configuration of the `FlowAction` for a landing page
 */
export function defineLandingPageController(url, intentFactory, prepareAction) {
    const intentKind = `LandingPage_${url.substring(1)}_Intent`;
    const { routes, makeCanonicalUrl } = generateRoutes((locale) => ({
        ...locale,
        $kind: intentKind,
    }), url, [], {
        exclusions: [
            {
                query: ["term"],
            },
        ],
    });
    return {
        $intentKind: intentKind,
        routes,
        async perform(landingPageIntent, objectGraph) {
            var _a;
            const pageIntent = intentFactory({
                storefront: landingPageIntent.storefront,
                language: landingPageIntent.language,
            });
            const viewModel = await objectGraph.dispatcher.dispatch(pageIntent, objectGraph);
            if (viewModel) {
                // Override the default canonical URL to use the vanity URL instead; this ensures
                // that the navigation mechanics of the "web" client respect the vanity URL, which the
                // Media API would not know about when providing it's own value for this property
                // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of
                // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require
                // from the intent is the locale information
                viewModel.canonicalURL = makeCanonicalUrl(objectGraph, landingPageIntent);
                (_a = objectGraph.seo) === null || _a === void 0 ? void 0 : _a.updateCanonicalURL(viewModel, viewModel.canonicalURL);
                // If the web navigation has already been injected, the active state of the "tabs" will be incorrect
                // since non-"landing pages" never have display active landing page links. We need to update the
                // navigation shelf, if it exists, based on the `landingPageIntent`
                updateWebNavigation(objectGraph, viewModel, unwrap(pageIntent.platform), landingPageIntent);
            }
            return viewModel;
        },
        buildIntent(locale) {
            return {
                ...locale,
                $kind: intentKind,
            };
        },
        buildAction(locale, objectGraph) {
            const intent = this.buildIntent(locale);
            return this.actionFor(intent, objectGraph, {});
        },
        actionFor(landingPageIntent, objectGraph) {
            const action = new FlowAction("page");
            action.destination = landingPageIntent;
            // @ts-expect-error TypeScript can't know that `landingPageIntent` satisfies the requirements of
            // `makeCanonicalUrl`, but this will be safe at runtime because all we actually require
            // from the intent is the locale information
            action.pageUrl = makeCanonicalUrl(objectGraph, landingPageIntent);
            prepareAction === null || prepareAction === void 0 ? void 0 : prepareAction(objectGraph, action);
            return action;
        },
    };
}
/**
 * Dynamically create an {@linkcode IntentController} that redirects from the platform root
 * to the default landing page
 *
 * @param url the URL for the platform to redirect for
 * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to
 */
export function definePlatformRootRedirectController(url, intentFactory) {
    const intentKind = `PlatformRootRedirect_${url.substring(1)}_Intent`;
    const { routes } = generateRoutes((locale) => ({
        ...locale,
        $kind: intentKind,
    }), url);
    return {
        $intentKind: intentKind,
        routes,
        async perform(landingPageIntent, objectGraph) {
            const pageIntent = intentFactory({
                storefront: landingPageIntent.storefront,
                language: landingPageIntent.language,
            });
            return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph);
        },
    };
}
/**
 * Dynamically create an {@linkcode IntentController} that redirects from the root
 * to the default landing page
 *
 * @param intentFactory a function that produces the `Intent` for the `LandingPageController` that should be delegated to
 */
export function defineRootRedirectController(intentFactory) {
    const intentKind = `RootRedirect_Intent`;
    const { routes } = generateRoutes((locale) => ({
        ...locale,
        $kind: intentKind,
    }), "/");
    return {
        $intentKind: intentKind,
        routes,
        async perform(landingPageIntent, objectGraph) {
            const pageIntent = intentFactory({
                storefront: landingPageIntent.storefront,
                language: landingPageIntent.language,
            });
            return await objectGraph.dispatcher.dispatch(pageIntent, objectGraph);
        },
    };
}
//# sourceMappingURL=platform-landing-page-utils.js.map