import { configuration } from '../../../../app/common-reducers.js';
import { specificFacetSearchSetReducer as facetSearchSet } from '../../../../features/facets/facet-search-set/specific/specific-facet-search-set-slice.js';
import { facetClearAll } from '../../../../features/facets/facet-set/facet-set-analytics-actions.js';
import { logFacetClearAll, logFacetShowLess, logFacetShowMore, logFacetUpdateSort, } from '../../../../features/facets/facet-set/facet-set-insight-analytics-actions.js';
import { getInsightAnalyticsActionForToggleFacetSelect } from '../../../../features/facets/facet-set/facet-set-insight-utils.js';
import { facetSetReducer as facetSet } from '../../../../features/facets/facet-set/facet-set-slice.js';
import { getAnalyticsActionForToggleFacetSelect } from '../../../../features/facets/facet-set/facet-set-utils.js';
import { executeSearch, fetchFacetValues, } from '../../../../features/insight-search/insight-search-actions.js';
import { searchReducer as search } from '../../../../features/search/search-slice.js';
import { loadReducerError } from '../../../../utils/errors.js';
import { buildCoreFacet, } from '../../../core/facets/facet/headless-core-facet.js';
import { facetOptionsSchema, } from './headless-insight-facet-options.js';
/**
 * Creates an insight `Facet` controller instance.
 *
 * @param engine - The insight engine.
 * @param props - The configurable `Facet` properties.
 * @returns A `Facet` controller instance.
 *
 * @group Controllers
 * @category Facet
 */
export function buildFacet(engine, props) {
    if (!loadFacetReducers(engine)) {
        throw loadReducerError;
    }
    const { dispatch } = engine;
    const coreController = buildCoreFacet(engine, {
        ...props,
        options: {
            ...props.options,
            ...(props.options.allowedValues && {
                allowedValues: {
                    type: 'simple',
                    values: props.options.allowedValues,
                },
            }),
        },
    }, facetOptionsSchema);
    const getFacetId = () => coreController.state.facetId;
    const createNoopFacetSearch = () => {
        return {
            updateText() { },
            showMoreResults() { },
            search() { },
            clear() { },
            updateCaptions() { },
            select() { },
            exclude() { },
            singleSelect() { },
            singleExclude() { },
            get state() {
                return {
                    values: [],
                    isLoading: false,
                    moreValuesAvailable: false,
                    query: '',
                };
            },
        };
    };
    const facetSearch = createNoopFacetSearch();
    const { state, ...restOfFacetSearch } = facetSearch;
    return {
        ...coreController,
        facetSearch: restOfFacetSearch,
        toggleSelect(selection) {
            coreController.toggleSelect(selection);
            dispatch(executeSearch({
                legacy: getInsightAnalyticsActionForToggleFacetSelect(getFacetId(), selection),
                next: getAnalyticsActionForToggleFacetSelect(selection),
            }));
        },
        deselectAll() {
            coreController.deselectAll();
            dispatch(executeSearch({
                legacy: logFacetClearAll(getFacetId()),
                next: facetClearAll(),
            }));
        },
        sortBy(sortCriterion) {
            coreController.sortBy(sortCriterion);
            dispatch(executeSearch({
                legacy: logFacetUpdateSort({ facetId: getFacetId(), sortCriterion }),
            }));
        },
        isSortedBy(criterion) {
            return this.state.sortCriterion === 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 loadFacetReducers(engine) {
    engine.addReducers({ facetSet, configuration, facetSearchSet, search });
    return true;
}
