import { BooleanValue, Schema } from '@coveo/bueno';
import { configuration } from '../../app/common-reducers.js';
import { disableDebug, enableDebug } from '../../features/debug/debug-actions.js';
import { rankingInformationSelector } from '../../features/debug/debug-selectors.js';
import { debugReducer as debug } from '../../features/debug/debug-slice.js';
import { disableFetchAllFields, enableFetchAllFields, fetchFieldsDescription, } from '../../features/fields/fields-actions.js';
import { fieldsReducer as fields } from '../../features/fields/fields-slice.js';
import { searchReducer as search } from '../../features/search/search-slice.js';
import { loadReducerError } from '../../utils/errors.js';
import { validateInitialState } from '../../utils/validate-payload.js';
import { buildController, } from '../controller/headless-controller.js';
const initialStateSchema = new Schema({
    enabled: new BooleanValue({ default: false }),
});
/**
 * Creates a `RelevanceInspector` controller instance.
 *
 * @param engine - The headless engine.
 * @param props - The configurable `RelevanceInspector` properties.
 * @returns A `RelevanceInspector` controller instance.
 *
 * @group Controllers
 * @category RelevanceInspector
 */
export function buildRelevanceInspector(engine, props = {}) {
    if (!loadRelevanceInspectorReducers(engine)) {
        throw loadReducerError;
    }
    const controller = buildController(engine);
    const { dispatch } = engine;
    const getState = () => engine.state;
    const initialState = validateInitialState(engine, initialStateSchema, props.initialState, 'buildRelevanceInspector');
    if (initialState.enabled) {
        dispatch(enableDebug());
    }
    const warnProductionEnvironment = (flag) => {
        engine.logger.warn(`Flag [ ${flag} ] is now activated. This should *not* be used in any production environment as it negatively impact performance.`);
    };
    return {
        ...controller,
        get state() {
            const state = getState();
            const isEnabled = state.debug;
            if (!state.debug) {
                return { isEnabled };
            }
            const { executionReport, basicExpression, advancedExpression, constantExpression, userIdentities, rankingExpressions, } = state.search.response;
            const { fieldsDescription, fetchAllFields } = state.fields;
            return {
                isEnabled,
                rankingInformation: rankingInformationSelector(state),
                executionReport,
                expressions: {
                    basicExpression,
                    advancedExpression,
                    constantExpression,
                },
                userIdentities,
                rankingExpressions,
                fieldsDescription,
                fetchAllFields,
            };
        },
        enable() {
            dispatch(enableDebug());
            warnProductionEnvironment('debug');
        },
        disable() {
            dispatch(disableDebug());
            dispatch(disableFetchAllFields());
        },
        enableFetchAllFields() {
            dispatch(enableFetchAllFields());
            warnProductionEnvironment('fetchAllFields');
        },
        disableFetchAllFields() {
            dispatch(disableFetchAllFields());
        },
        fetchFieldsDescription() {
            !this.state.isEnabled && dispatch(enableDebug());
            dispatch(fetchFieldsDescription());
            warnProductionEnvironment('fieldsDescription');
            engine.logger.warn(`For production environment, please specify the necessary fields either when instantiating a ResultList controller, or by dispatching a registerFieldsToInclude action.
        
        hhttps://docs.coveo.com/en/headless/latest/reference/interfaces/Search.ResultListOptions.html
        https://docs.coveo.com/en/headless/latest/reference/interfaces/Search.FieldActionCreators.html#registerfieldstoinclude`);
        },
    };
}
function loadRelevanceInspectorReducers(engine) {
    engine.addReducers({
        debug,
        search,
        configuration,
        fields,
    });
    return true;
}
