import { configuration } from '../../../app/common-reducers.js';
import { stateKey } from '../../../app/state-key.js';
import { contextReducer as commerceContext } from '../../../features/commerce/context/context-slice.js';
import { pagePrincipalSelector, perPagePrincipalSelector, totalEntriesPrincipalSelector, } from '../../../features/commerce/pagination/pagination-selectors.js';
import { searchSerializer } from '../../../features/commerce/parameters/parameters-serializer.js';
import { queryReducer as commerceQuery } from '../../../features/commerce/query/query-slice.js';
import { executeSearch, fetchMoreProducts, promoteChildToParent, } from '../../../features/commerce/search/search-actions.js';
import { activeParametersSelector, enrichedSummarySelector, errorSelector, isLoadingSelector, numberOfProductsSelector, requestIdSelector, responseIdSelector, } from '../../../features/commerce/search/search-selectors.js';
import { commerceSearchReducer as commerceSearch } from '../../../features/commerce/search/search-slice.js';
import { restoreSearchParameters } from '../../../features/commerce/search-parameters/search-parameters-actions.js';
import { searchParametersDefinition } from '../../../features/commerce/search-parameters/search-parameters-schema.js';
import { loadReducerError } from '../../../utils/errors.js';
import { buildController, } from '../../controller/headless-controller.js';
import { buildSearchSubControllers, } from '../core/sub-controller/headless-sub-controller.js';
import { facetResponseSelector, isFacetLoadingResponseSelector, } from './facets/headless-search-facet-options.js';
/**
 * Builds a `Search` controller for the given commerce engine.
 * @param engine - The commerce engine.
 * @returns A `Search` controller.
 *
 * @group Buildable controllers
 * @category Search
 */
export function buildSearch(engine) {
    if (!loadBaseSearchReducers(engine)) {
        throw loadReducerError;
    }
    const controller = buildController(engine);
    const { dispatch } = engine;
    const getState = () => engine[stateKey];
    const subControllers = buildSearchSubControllers(engine, {
        responseIdSelector,
        fetchProductsActionCreator: executeSearch,
        fetchMoreProductsActionCreator: fetchMoreProducts,
        facetResponseSelector,
        isFacetLoadingResponseSelector,
        requestIdSelector,
        serializer: searchSerializer,
        parametersDefinition: searchParametersDefinition,
        restoreActionCreator: restoreSearchParameters,
        activeParametersSelector,
        isLoadingSelector,
        errorSelector,
        pageSelector: pagePrincipalSelector,
        perPageSelector: perPagePrincipalSelector,
        totalEntriesSelector: totalEntriesPrincipalSelector,
        numberOfProductsSelector,
        enrichSummary: enrichedSummarySelector,
    });
    return {
        ...controller,
        ...subControllers,
        get state() {
            return getState().commerceSearch;
        },
        promoteChildToParent(child) {
            dispatch(promoteChildToParent({ child }));
        },
        executeFirstSearch() {
            const firstSearchExecuted = responseIdSelector(getState()) !== '';
            if (firstSearchExecuted) {
                return;
            }
            dispatch(executeSearch());
        },
    };
}
function loadBaseSearchReducers(engine) {
    engine.addReducers({
        commerceContext,
        configuration,
        commerceSearch,
        commerceQuery,
    });
    return true;
}
