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 { parametersDefinition } from '../../../features/commerce/parameters/parameters-schema.js';
import { activeParametersSelector } from '../../../features/commerce/parameters/parameters-selectors.js';
import { productListingSerializer } from '../../../features/commerce/parameters/parameters-serializer.js';
import { fetchMoreProducts, fetchProductListing, promoteChildToParent, } from '../../../features/commerce/product-listing/product-listing-actions.js';
import { errorSelector, isLoadingSelector, numberOfProductsSelector, requestIdSelector, responseIdSelector, } from '../../../features/commerce/product-listing/product-listing-selectors.js';
import { productListingReducer as productListing } from '../../../features/commerce/product-listing/product-listing-slice.js';
import { restoreProductListingParameters } from '../../../features/commerce/product-listing-parameters/product-listing-parameters-actions.js';
import { loadReducerError } from '../../../utils/errors.js';
import { buildController, } from '../../controller/headless-controller.js';
import { buildProductListingSubControllers, } from '../core/sub-controller/headless-sub-controller.js';
import { facetResponseSelector, isFacetLoadingResponseSelector, } from './facets/headless-product-listing-facet-options.js';
/**
 * Creates a `ProductListing` controller instance.
 *
 * @param engine - The headless commerce engine.
 * @returns A `ProductListing` controller instance.
 *
 * @group Buildable controllers
 * @category ProductListing
 */
export function buildProductListing(engine) {
    if (!loadBaseProductListingReducers(engine)) {
        throw loadReducerError;
    }
    const controller = buildController(engine);
    const { dispatch } = engine;
    const getState = () => engine[stateKey];
    const subControllers = buildProductListingSubControllers(engine, {
        responseIdSelector,
        fetchProductsActionCreator: fetchProductListing,
        fetchMoreProductsActionCreator: fetchMoreProducts,
        facetResponseSelector,
        isFacetLoadingResponseSelector,
        requestIdSelector,
        serializer: productListingSerializer,
        parametersDefinition,
        activeParametersSelector,
        restoreActionCreator: restoreProductListingParameters,
        isLoadingSelector,
        errorSelector,
        pageSelector: pagePrincipalSelector,
        perPageSelector: perPagePrincipalSelector,
        totalEntriesSelector: totalEntriesPrincipalSelector,
        numberOfProductsSelector,
    });
    return {
        ...controller,
        ...subControllers,
        get state() {
            const { products, error, isLoading, responseId } = getState().productListing;
            return {
                products,
                error,
                isLoading,
                responseId,
            };
        },
        promoteChildToParent(child) {
            dispatch(promoteChildToParent({ child }));
        },
        refresh: () => dispatch(fetchProductListing()),
        executeFirstRequest() {
            const firstRequestExecuted = responseIdSelector(getState()) !== '';
            if (firstRequestExecuted) {
                return;
            }
            dispatch(fetchProductListing());
        },
    };
}
function loadBaseProductListingReducers(engine) {
    engine.addReducers({ productListing, commerceContext, configuration });
    return true;
}
