import { configuration } from '../../../app/common-reducers.js';
import { updateFacetOptions } from '../../../features/facet-options/facet-options-actions.js';
import { categoryFacetSetReducer as categoryFacetSet } from '../../../features/facets/category-facet-set/category-facet-set-slice.js';
import { categoryFacetSearchSetReducer as categoryFacetSearchSet } from '../../../features/facets/facet-search-set/category/category-facet-search-set-slice.js';
import { executeFacetSearch, executeFieldSuggest, } from '../../../features/facets/facet-search-set/generic/generic-facet-search-actions.js';
import { facetClearAll, facetDeselect, facetSelect, logFacetClearAll, logFacetDeselect, logFacetSelect, logFacetShowLess, logFacetShowMore, logFacetUpdateSort, } from '../../../features/facets/facet-set/facet-set-analytics-actions.js';
import { executeSearch, fetchFacetValues, } from '../../../features/search/search-actions.js';
import { searchReducer as search } from '../../../features/search/search-slice.js';
import { loadReducerError } from '../../../utils/errors.js';
import { buildCoreCategoryFacet, } from '../../core/facets/category-facet/headless-core-category-facet.js';
import { buildCategoryFacetSearch } from './headless-category-facet-search.js';
/**
 * Creates a `CategoryFacet` controller instance.
 *
 * @param engine - The headless engine.
 * @param props - The configurable `CategoryFacet` properties.
 * @returns A `CategoryFacet` controller instance.
 *
 * @group Controllers
 * @category CategoryFacet
 * */
export function buildCategoryFacet(engine, props) {
    if (!loadCategoryFacetReducers(engine)) {
        throw loadReducerError;
    }
    const coreController = buildCoreCategoryFacet(engine, props);
    const { dispatch } = engine;
    const getFacetId = () => coreController.state.facetId;
    const facetSearch = buildCategoryFacetSearch(engine, {
        options: {
            facetId: getFacetId(),
            ...props.options.facetSearch,
        },
        executeFacetSearchActionCreator: executeFacetSearch,
        executeFieldSuggestActionCreator: executeFieldSuggest,
        select: (value) => {
            dispatch(updateFacetOptions());
            dispatch(executeSearch({
                legacy: logFacetSelect({
                    facetId: getFacetId(),
                    facetValue: value.rawValue,
                }),
                next: facetSelect(),
            }));
        },
        isForFieldSuggestions: false,
    });
    const { state, ...restOfFacetSearch } = facetSearch;
    return {
        ...coreController,
        facetSearch: restOfFacetSearch,
        toggleSelect(selection) {
            coreController.toggleSelect(selection);
            dispatch(executeSearch({
                legacy: getLegacyToggleSelectAnalyticsAction(getFacetId(), selection),
                next: getToggleSelectAnalyticsAction(selection),
            }));
        },
        deselectAll() {
            coreController.deselectAll();
            dispatch(executeSearch({
                legacy: logFacetClearAll(getFacetId()),
                next: facetClearAll(),
            }));
        },
        sortBy(criterion) {
            coreController.sortBy(criterion);
            dispatch(executeSearch({
                legacy: logFacetUpdateSort({ facetId: getFacetId(), criterion }),
            }));
        },
        showMoreValues() {
            coreController.showMoreValues();
            dispatch(fetchFacetValues({ legacy: logFacetShowMore(getFacetId()) }));
        },
        showLessValues() {
            coreController.showLessValues();
            dispatch(fetchFacetValues({ legacy: logFacetShowLess(getFacetId()) }));
        },
        get state() {
            return {
                ...coreController.state,
                facetSearch: facetSearch.state,
            };
        },
    };
}
function loadCategoryFacetReducers(engine) {
    engine.addReducers({
        categoryFacetSet,
        categoryFacetSearchSet,
        configuration,
        search,
    });
    return true;
}
function getLegacyToggleSelectAnalyticsAction(facetId, selection) {
    const payload = {
        facetId,
        facetValue: selection.value,
    };
    const isSelected = selection.state === 'selected';
    return isSelected ? logFacetDeselect(payload) : logFacetSelect(payload);
}
function getToggleSelectAnalyticsAction(selection) {
    const isSelected = selection.state === 'selected';
    return isSelected ? facetDeselect() : facetSelect();
}
