import { GeneratedAnswerAPIClient } from '../../api/generated-answer/generated-answer-client.js';
import { NoopPreprocessRequest } from '../../api/preprocess-request.js';
import { InsightAPIClient } from '../../api/service/insight/insight-api-client.js';
import { interfaceLoad } from '../../features/analytics/analytics-actions.js';
import { updateSearchConfiguration, } from '../../features/configuration/configuration-actions.js';
import { setInsightConfiguration } from '../../features/insight-configuration/insight-configuration-actions.js';
import { insightConfigurationReducer as insightConfiguration } from '../../features/insight-configuration/insight-configuration-slice.js';
import { fetchInterface } from '../../features/insight-interface/insight-interface-actions.js';
import { insightInterfaceReducer as insightInterface } from '../../features/insight-interface/insight-interface-slice.js';
import { executeSearch } from '../../features/insight-search/insight-search-actions.js';
import { logInsightInterfaceLoad } from '../../features/insight-search/insight-search-analytics-actions.js';
import { resultPreviewReducer as resultPreview } from '../../features/result-preview/result-preview-slice.js';
import { firstSearchExecutedSelector } from '../../features/search/search-selectors.js';
import { searchReducer as search } from '../../features/search/search-slice.js';
import { searchHubReducer as searchHub } from '../../features/search-hub/search-hub-slice.js';
import { buildEngine, warnIfUsingNextAnalyticsModeForServiceFeature, } from '../engine.js';
import { buildLogger } from '../logger.js';
import { buildThunkExtraArguments } from '../thunk-extra-arguments.js';
import { getSampleInsightEngineConfiguration, insightEngineConfigurationSchema, } from './insight-engine-configuration.js';
export { getSampleInsightEngineConfiguration };
const insightEngineReducers = {
    insightConfiguration,
    search,
    insightInterface,
    searchHub,
    resultPreview,
};
function getUpdateSearchConfigurationPayload(configuration) {
    const { search } = configuration;
    if (!search) {
        return;
    }
    const { locale, proxyBaseUrl } = search;
    return {
        locale,
        proxyBaseUrl,
    };
}
/**
 * Creates an insight engine instance.
 *
 * @param options - The insight engine options.
 * @returns An insight engine instance.
 *
 * @group Engine
 */
export function buildInsightEngine(options) {
    const logger = buildLogger(options.loggerOptions);
    validateConfiguration(options.configuration, logger);
    const insightAPIClient = createInsightAPIClient(options.configuration, logger);
    const generatedAnswerClient = createGeneratedAnswerAPIClient(logger);
    const thunkArguments = {
        ...buildThunkExtraArguments(options.configuration, logger),
        apiClient: insightAPIClient,
        streamingClient: generatedAnswerClient,
    };
    const augmentedOptions = {
        ...options,
        reducers: insightEngineReducers,
    };
    const engine = buildEngine(augmentedOptions, thunkArguments);
    warnIfUsingNextAnalyticsModeForServiceFeature(engine.state.configuration.analytics.analyticsMode);
    const { insightId } = options.configuration;
    const search = getUpdateSearchConfigurationPayload(options.configuration);
    engine.dispatch(setInsightConfiguration({
        insightId,
    }));
    engine.dispatch(fetchInterface());
    if (search) {
        engine.dispatch(updateSearchConfiguration(search));
    }
    return {
        ...engine,
        get state() {
            return engine.state;
        },
        executeFirstSearch(analyticsEvent = logInsightInterfaceLoad()) {
            const firstSearchExecuted = firstSearchExecutedSelector(engine.state);
            if (firstSearchExecuted) {
                return;
            }
            engine.dispatch(executeSearch({ legacy: analyticsEvent, next: interfaceLoad() }));
        },
    };
}
function validateConfiguration(configuration, logger) {
    try {
        insightEngineConfigurationSchema.validate(configuration);
    }
    catch (error) {
        logger.error(error, 'Insight engine configuration error');
        throw error;
    }
}
function createInsightAPIClient(configuration, logger) {
    return new InsightAPIClient({
        logger,
        preprocessRequest: configuration.preprocessRequest || NoopPreprocessRequest,
    });
}
function createGeneratedAnswerAPIClient(logger) {
    return new GeneratedAnswerAPIClient({
        logger,
    });
}
