import { createAsyncThunk } from '@reduxjs/toolkit';
import HistoryStore from '../../api/analytics/coveo.analytics/history-store.js';
import { isErrorResponse, } from '../../api/search/search-api-client.js';
import { requiredNonEmptyString } from '../../utils/validate-payload.js';
import { SearchPageEvents } from '../analytics/search-action-cause.js';
import { updateSearchAction, } from '../search/search-actions.js';
import { mapSearchResponse, } from '../search/search-mappings.js';
import { buildInsightQuerySuggestRequest } from './insight-query-suggest-request.js';
import { AsyncInsightSearchThunkProcessor, } from './insight-search-actions-thunk-processor.js';
import { buildInsightFetchFacetValuesRequest, buildInsightFetchMoreResultsRequest, buildInsightSearchRequest, } from './insight-search-request.js';
import { legacyExecuteSearch, legacyFetchFacetValues, legacyFetchMoreResults, legacyFetchPage, } from './legacy/insight-search-actions.js';
export const fetchFromAPI = async (client, state, { request, mappings }, options) => {
    const startedAt = Date.now();
    const response = mapSearchResponse(await client.query(request, options), mappings);
    const duration = Date.now() - startedAt;
    const queryExecuted = state.query?.q || '';
    return {
        response,
        duration,
        queryExecuted,
        requestExecuted: request,
    };
};
export const executeSearch = createAsyncThunk('search/executeSearch', async (analyticsAction, config) => {
    const state = config.getState();
    if (state.configuration.analytics.analyticsMode === 'legacy') {
        return legacyExecuteSearch(state, config, analyticsAction.legacy);
    }
    addEntryInActionsHistory(state);
    const processor = new AsyncInsightSearchThunkProcessor({
        ...config,
    });
    const eventDescription = analyticsAction.next
        ? buildEventDescription(analyticsAction.next)
        : undefined;
    config.dispatch(updateSearchAction(analyticsAction.next));
    const request = await buildInsightSearchRequest(state, eventDescription);
    const fetched = await processor.fetchFromAPI(request);
    return await processor.process(fetched);
});
export const fetchPage = createAsyncThunk('search/fetchPage', async (analyticsAction, config) => {
    const state = config.getState();
    if (state.configuration.analytics.analyticsMode === 'legacy') {
        return legacyFetchPage(state, config, analyticsAction.legacy);
    }
    addEntryInActionsHistory(state);
    const processor = new AsyncInsightSearchThunkProcessor({
        ...config,
    });
    const eventDescription = analyticsAction.next
        ? buildEventDescription(analyticsAction.next)
        : undefined;
    const request = await buildInsightSearchRequest(state, eventDescription);
    const fetched = await processor.fetchFromAPI(request);
    return await processor.process(fetched);
});
export const fetchMoreResults = createAsyncThunk('search/fetchMoreResults', async (_, config) => {
    const state = config.getState();
    if (state.configuration.analytics.analyticsMode === 'legacy') {
        return legacyFetchMoreResults(state, config);
    }
    const processor = new AsyncInsightSearchThunkProcessor({
        ...config,
    });
    const eventDescription = buildEventDescription({
        actionCause: SearchPageEvents.browseResults,
    });
    const request = await buildInsightFetchMoreResultsRequest(state, eventDescription);
    const fetched = await processor.fetchFromAPI(request);
    return await processor.process(fetched);
});
export const fetchFacetValues = createAsyncThunk('search/fetchFacetValues', async (analyticsAction, config) => {
    const state = config.getState();
    if (state.configuration.analytics.analyticsMode === 'legacy') {
        return legacyFetchFacetValues(state, config, analyticsAction.legacy);
    }
    const processor = new AsyncInsightSearchThunkProcessor({
        ...config,
    });
    const request = await buildInsightFetchFacetValuesRequest(state);
    const fetched = await processor.fetchFromAPI(request);
    return await processor.process(fetched);
});
export const fetchQuerySuggestions = createAsyncThunk('querySuggest/fetch', async (payload, { getState, rejectWithValue, extra: { apiClient, validatePayload } }) => {
    validatePayload(payload, {
        id: requiredNonEmptyString,
    });
    const id = payload.id;
    const request = await buildInsightQuerySuggestRequest(id, getState());
    const response = await apiClient.querySuggest(request);
    if (isErrorResponse(response)) {
        return rejectWithValue(response.error);
    }
    return {
        id,
        q: request.q,
        ...response.success,
    };
});
export const addEntryInActionsHistory = (state) => {
    if (state.configuration.analytics.enabled) {
        HistoryStore.getInstance().addElement({
            name: 'Query',
            ...(state.query?.q && {
                value: state.query.q,
            }),
            time: JSON.stringify(new Date()),
        });
    }
};
const buildEventDescription = (action) => ({
    actionCause: action.actionCause,
    type: action.actionCause,
});
