/**
 * Utility functions to be used for Commerce Server Side Rendering.
 */
import { buildFactory, } from '../factories/build-factory.js';
import { hydratedStaticStateFactory } from '../factories/hydrated-state-factory.js';
import { hydratedRecommendationStaticStateFactory } from '../factories/recommendation-hydrated-state-factory.js';
import { fetchRecommendationStaticStateFactory } from '../factories/recommendation-static-state-factory.js';
import { fetchStaticStateFactory } from '../factories/static-state-factory.js';
import { SolutionType } from '../types/controller-constants.js';
/**
 * Initializes a Commerce engine definition in SSR with given controllers definitions and commerce engine config.
 * @param options - The commerce engine definition
 * @returns Three utility functions to fetch the initial state of the engine in SSR, hydrate the state in CSR,
 *  and a build function that can be used for edge cases requiring more control.
 *
 * @group Engine
 */
export function defineCommerceEngine(options) {
    const { controllers: controllerDefinitions, ...engineOptions } = options;
    const getOptions = () => engineOptions;
    const setNavigatorContextProvider = (navigatorContextProvider) => {
        engineOptions.navigatorContextProvider = navigatorContextProvider;
    };
    const getAccessToken = () => engineOptions.configuration.accessToken;
    const setAccessToken = (accessToken) => {
        engineOptions.configuration.accessToken = accessToken;
    };
    const build = buildFactory(controllerDefinitions, getOptions());
    const fetchStaticState = fetchStaticStateFactory(controllerDefinitions, getOptions());
    const hydrateStaticState = hydratedStaticStateFactory(controllerDefinitions, getOptions());
    const fetchRecommendationStaticState = fetchRecommendationStaticStateFactory(controllerDefinitions, getOptions());
    const hydrateRecommendationStaticState = hydratedRecommendationStaticStateFactory(controllerDefinitions, getOptions());
    return {
        listingEngineDefinition: {
            build: build(SolutionType.listing),
            fetchStaticState: fetchStaticState(SolutionType.listing),
            hydrateStaticState: hydrateStaticState(SolutionType.listing),
            setNavigatorContextProvider,
            getAccessToken,
            setAccessToken,
        },
        searchEngineDefinition: {
            build: build(SolutionType.search),
            fetchStaticState: fetchStaticState(SolutionType.search),
            hydrateStaticState: hydrateStaticState(SolutionType.search),
            setNavigatorContextProvider,
            getAccessToken,
            setAccessToken,
        },
        recommendationEngineDefinition: {
            build: build(SolutionType.recommendation),
            fetchStaticState: fetchRecommendationStaticState,
            hydrateStaticState: hydrateRecommendationStaticState,
            setNavigatorContextProvider,
            getAccessToken,
            setAccessToken,
        },
        // TODO KIT-3738 :  The standaloneEngineDefinition should not be async since no request is sent to the API
        standaloneEngineDefinition: {
            build: build(SolutionType.standalone),
            fetchStaticState: fetchStaticState(SolutionType.standalone),
            hydrateStaticState: hydrateStaticState(SolutionType.standalone),
            setNavigatorContextProvider,
            getAccessToken,
            setAccessToken,
        },
    };
}
