import { getDebugInitialState } from '../../features/debug/debug-state.js';
import { getPaginationInitialState } from '../../features/pagination/pagination-state.js';
import { getQueryInitialState } from '../../features/query/query-state.js';
import { executeSearch } from '../../features/search/search-actions.js';
import { legacyLogParametersChange, parametersChange, } from '../../features/search-parameters/search-parameter-analytics-actions.js';
import { deepEqualAnyOrder } from '../../utils/compare-utils.js';
import { buildCoreSearchParameterManager, enrichParameters, getCoreActiveSearchParameters, } from '../core/search-parameter-manager/headless-core-search-parameter-manager.js';
/**
 * Creates a `SearchParameterManager` controller instance.
 *
 * @param engine - The headless engine.
 * @param props - The configurable `SearchParameterManager` properties.
 * @returns A `SearchParameterManager` controller instance.
 *
 * @group Controllers
 * @category SearchParameterManager
 */
export function buildSearchParameterManager(engine, props) {
    const { dispatch } = engine;
    const controller = buildCoreSearchParameterManager(engine, props);
    return {
        ...controller,
        synchronize(parameters) {
            const activeParams = getActiveSearchParameters(engine);
            const oldParams = enrichParameters(engine, activeParams);
            const newParams = enrichParameters(engine, parameters);
            if (deepEqualAnyOrder(oldParams, newParams)) {
                return;
            }
            controller.synchronize(parameters);
            dispatch(executeSearch({
                legacy: legacyLogParametersChange(oldParams, newParams),
                next: parametersChange(oldParams, newParams),
            }));
        },
        get state() {
            const parameters = getActiveSearchParameters(engine);
            return { parameters };
        },
    };
}
function getActiveSearchParameters(engine) {
    const state = engine.state;
    return {
        ...getCoreActiveSearchParameters(engine),
        ...getEnableQuerySyntax(state),
        ...getAq(state),
        ...getCq(state),
        ...getFirstResult(state),
        ...getNumberOfResults(state),
        ...getDebug(state),
        ...getStaticFilters(state),
    };
}
function getEnableQuerySyntax(state) {
    if (state.query === undefined) {
        return {};
    }
    const enableQuerySyntax = state.query.enableQuerySyntax;
    const shouldInclude = enableQuerySyntax !== undefined &&
        enableQuerySyntax !== getQueryInitialState().enableQuerySyntax;
    return shouldInclude ? { enableQuerySyntax } : {};
}
function getAq(state) {
    if (state.advancedSearchQueries === undefined) {
        return {};
    }
    const { aq, defaultFilters } = state.advancedSearchQueries;
    const shouldInclude = aq !== defaultFilters.aq;
    return shouldInclude ? { aq } : {};
}
function getCq(state) {
    if (state.advancedSearchQueries === undefined) {
        return {};
    }
    const { cq, defaultFilters } = state.advancedSearchQueries;
    const shouldInclude = cq !== defaultFilters.cq;
    return shouldInclude ? { cq } : {};
}
function getFirstResult(state) {
    if (state.pagination === undefined) {
        return {};
    }
    const firstResult = state.pagination.firstResult;
    const shouldInclude = firstResult !== getPaginationInitialState().firstResult;
    return shouldInclude ? { firstResult } : {};
}
function getNumberOfResults(state) {
    if (state.pagination === undefined) {
        return {};
    }
    const { numberOfResults, defaultNumberOfResults } = state.pagination;
    const shouldInclude = numberOfResults !== defaultNumberOfResults;
    return shouldInclude ? { numberOfResults } : {};
}
function getStaticFilters(state) {
    if (state.staticFilterSet === undefined) {
        return {};
    }
    const sf = Object.entries(state.staticFilterSet)
        .map(([id, filter]) => {
        const selectedCaptions = getSelectedStaticFilterCaptions(filter.values);
        return selectedCaptions.length ? { [id]: selectedCaptions } : {};
    })
        // oxlint-disable-next-line oxc/no-accumulating-spread -- <>
        .reduce((acc, obj) => ({ ...acc, ...obj }), {});
    return Object.keys(sf).length ? { sf } : {};
}
function getSelectedStaticFilterCaptions(values) {
    return values.filter((v) => v.state === 'selected').map((v) => v.caption);
}
function getDebug(state) {
    if (state.debug === undefined) {
        return {};
    }
    const debug = state.debug;
    const shouldInclude = debug !== getDebugInitialState();
    return shouldInclude ? { debug } : {};
}
