import { createSelector } from '@reduxjs/toolkit';
import { stateKey } from '../../../app/state-key.js';
import { pageRecommendationSelector, perPageRecommendationSelector, totalEntriesRecommendationSelector, } from '../../../features/commerce/pagination/pagination-selectors.js';
import { recommendationsOptionsSchema } from '../../../features/commerce/recommendations/recommendations.js';
import { fetchMoreRecommendations, fetchRecommendations, promoteChildToParent, registerRecommendationsSlot, } from '../../../features/commerce/recommendations/recommendations-actions.js';
import { isLoadingSelector, numberOfRecommendationsSelector, } from '../../../features/commerce/recommendations/recommendations-selectors.js';
import { recommendationsReducer as recommendations } from '../../../features/commerce/recommendations/recommendations-slice.js';
import { loadReducerError } from '../../../utils/errors.js';
import { validateInitialState } from '../../../utils/validate-payload.js';
import { buildController, } from '../../controller/headless-controller.js';
import { buildBaseSubControllers, } from '../core/sub-controller/headless-sub-controller.js';
/**
 * Creates a `Recommendations` controller instance.
 *
 * @param engine - The headless commerce engine.
 * @param props - The configurable `Recommendations` controller properties.
 * @returns A `Recommendations` controller instance.
 *
 * @group Buildable controllers
 * @category Recommendations
 */
export function buildRecommendations(engine, props) {
    if (!loadBaseRecommendationsReducers(engine)) {
        throw loadReducerError;
    }
    validateInitialState(engine, recommendationsOptionsSchema, props.options, 'buildRecommendations');
    const controller = buildController(engine);
    const { dispatch } = engine;
    const { slotId, productId } = props.options;
    dispatch(registerRecommendationsSlot({ slotId, productId }));
    const recommendationStateSelector = createSelector((state) => state.recommendations[slotId], (recommendations) => recommendations);
    const subControllers = buildBaseSubControllers(engine, {
        slotId,
        responseIdSelector: (state) => state.recommendations[slotId].responseId,
        fetchProductsActionCreator: () => fetchRecommendations({ slotId }),
        fetchMoreProductsActionCreator: () => fetchMoreRecommendations({ slotId }),
        isLoadingSelector: (state) => isLoadingSelector(state, slotId),
        errorSelector: (state) => state.recommendations[slotId].error,
        pageSelector: (state) => pageRecommendationSelector(state, slotId),
        perPageSelector: (state) => perPageRecommendationSelector(state, slotId),
        totalEntriesSelector: (state) => totalEntriesRecommendationSelector(state, slotId),
        numberOfProductsSelector: (state) => numberOfRecommendationsSelector(state, slotId),
    });
    return {
        ...controller,
        ...subControllers,
        promoteChildToParent(child) {
            dispatch(promoteChildToParent({ child, slotId }));
        },
        get state() {
            return recommendationStateSelector(engine[stateKey]);
        },
        refresh: () => dispatch(fetchRecommendations({ slotId, productId })),
    };
}
function loadBaseRecommendationsReducers(engine) {
    engine.addReducers({ recommendations });
    return true;
}
