import { configuration } from '../../../app/common-reducers.js';
import { stateKey } from '../../../app/state-key.js';
import { updateQuery } from '../../../features/commerce/query/query-actions.js';
import { queryReducer as commerceQuery } from '../../../features/commerce/query/query-slice.js';
import { commerceQuerySuggestReducer as querySuggest } from '../../../features/commerce/query-suggest/commerce-query-suggest-slice.js';
import { selectQuerySuggestion } from '../../../features/commerce/query-suggest/query-suggest-actions.js';
import { fetchRedirectUrl, registerStandaloneSearchBox, resetStandaloneSearchBox, updateStandaloneSearchBoxRedirectionUrl, } from '../../../features/commerce/standalone-search-box-set/standalone-search-box-set-actions.js';
import { commerceStandaloneSearchBoxSetReducer as commerceStandaloneSearchBoxSet } from '../../../features/commerce/standalone-search-box-set/standalone-search-box-set-slice.js';
import { loadReducerError } from '../../../utils/errors.js';
import { randomID } from '../../../utils/utils.js';
import { validateOptions } from '../../../utils/validate-payload.js';
import { buildSearchBox, } from '../search-box/headless-search-box.js';
import { defaultSearchBoxOptions } from '../search-box/headless-search-box-options.js';
import { standaloneSearchBoxSchema, } from './headless-standalone-search-box-options.js';
/**
 * Creates a `StandaloneSearchBox` controller instance.
 *
 * @param engine - The headless commerce engine.
 * @param props - The configurable `StandaloneSearchBox` properties.
 * @returns A `StandaloneSearchBox` controller instance.
 *
 * @group Buildable controllers
 * @category StandaloneSearchBox
 */
export function buildStandaloneSearchBox(engine, props) {
    if (!loadStandaloneSearchBoxReducers(engine)) {
        throw loadReducerError;
    }
    const { dispatch } = engine;
    const getState = () => engine[stateKey];
    const id = props.options.id || randomID('standalone_search_box');
    const options = {
        id,
        highlightOptions: { ...props.options.highlightOptions },
        ...defaultSearchBoxOptions,
        ...{ overwrite: false },
        ...props.options,
    };
    validateOptions(engine, standaloneSearchBoxSchema, options, 'buildStandaloneSearchBox');
    const searchBox = buildSearchBox(engine, { options });
    dispatch(registerStandaloneSearchBox({
        id,
        redirectionUrl: options.redirectionUrl,
        overwrite: options.overwrite,
    }));
    return {
        ...searchBox,
        updateText(value) {
            searchBox.updateText(value);
        },
        selectSuggestion(value) {
            dispatch(selectQuerySuggestion({ id, expression: value }));
            this.submit();
        },
        afterRedirection() {
            dispatch(resetStandaloneSearchBox({ id }));
        },
        updateRedirectUrl(url) {
            dispatch(updateStandaloneSearchBoxRedirectionUrl({ id, redirectionUrl: url }));
        },
        submit() {
            dispatch(updateQuery({
                query: this.state.value,
            }));
            dispatch(fetchRedirectUrl({ id }));
        },
        get state() {
            const state = getState();
            const standaloneSearchBoxState = state.commerceStandaloneSearchBoxSet[id];
            return {
                ...searchBox.state,
                redirectTo: standaloneSearchBoxState.redirectTo,
            };
        },
    };
}
function loadStandaloneSearchBoxReducers(engine) {
    engine.addReducers({
        commerceQuery,
        commerceStandaloneSearchBoxSet,
        configuration,
        querySuggest,
    });
    return true;
}
