import { BooleanValue, RecordValue, StringValue } from '@coveo/bueno';
import { createAction, createAsyncThunk } from '@reduxjs/toolkit';
import { isErrorResponse, } from '../../../api/commerce/commerce-api-client.js';
import { validatePayload } from '../../../utils/validate-payload.js';
import { buildBaseCommerceAPIRequest } from '../common/base-commerce-api-request-builder.js';
import { buildFilterableCommerceAPIRequest } from '../common/filterable-commerce-api-request-builder.js';
import { deleteAllCoreFacets, updateAutoSelectionForAllCoreFacets, } from '../facets/core-facet/core-facet-actions.js';
import { selectPage } from '../pagination/pagination-actions.js';
import { perPagePrincipalSelector } from '../pagination/pagination-selectors.js';
import { updateQuery } from '../query/query-actions.js';
import { AsyncSearchThunkProcessor, } from './search-actions-thunk-processor.js';
import { moreProductsAvailableSelector, numberOfProductsSelector, querySelector, } from './search-selectors.js';
export const executeSearch = createAsyncThunk('commerce/search/executeSearch', async (_action, config) => {
    const { getState } = config;
    const state = getState();
    const { navigatorContext } = config.extra;
    const request = buildFilterableCommerceAPIRequest(state, navigatorContext);
    const query = querySelector(state);
    const processor = new AsyncSearchThunkProcessor(config);
    const fetchedResponse = await processor.fetchFromAPI({ ...request, query });
    return processor.process(fetchedResponse);
});
export const fetchMoreProducts = createAsyncThunk('commerce/search/fetchMoreProducts', async (_action, config) => {
    const { getState } = config;
    const state = getState();
    const { navigatorContext } = config.extra;
    const moreProductsAvailable = moreProductsAvailableSelector(state);
    if (!moreProductsAvailable) {
        return null;
    }
    const perPage = perPagePrincipalSelector(state);
    const numberOfProducts = numberOfProductsSelector(state);
    const nextPageToRequest = numberOfProducts / perPage;
    const query = querySelector(state);
    const request = buildFilterableCommerceAPIRequest(state, navigatorContext);
    const processor = new AsyncSearchThunkProcessor(config);
    const fetchedResponse = await processor.fetchFromAPI({
        ...request,
        query,
        page: nextPageToRequest,
    });
    return processor.process(fetchedResponse);
});
export const prepareForSearchWithQuery = createAsyncThunk('commerce/search/prepareForSearchWithQuery', (payload, thunk) => {
    const { dispatch } = thunk;
    validatePayload(payload, {
        query: new StringValue(),
        clearFilters: new BooleanValue(),
    });
    if (payload.clearFilters) {
        dispatch(deleteAllCoreFacets());
    }
    dispatch(updateAutoSelectionForAllCoreFacets({ allow: true }));
    dispatch(updateQuery({
        query: payload.query,
    }));
    dispatch(selectPage({ page: 0 }));
});
export const fetchInstantProducts = createAsyncThunk('commerce/search/fetchInstantProducts', async (payload, { getState, rejectWithValue, extra }) => {
    const state = getState();
    const { apiClient, navigatorContext } = extra;
    const { q } = payload;
    const fetched = await apiClient.productSuggestions({
        ...buildBaseCommerceAPIRequest(state, navigatorContext),
        query: q,
    });
    if (isErrorResponse(fetched)) {
        return rejectWithValue(fetched.error);
    }
    return {
        response: { ...fetched.success, products: fetched.success.products },
    };
});
const promoteChildToParentDefinition = {
    child: new RecordValue({
        options: { required: true },
        values: {
            permanentid: new StringValue({ required: true }),
        },
    }),
};
export const promoteChildToParent = createAction('commerce/search/promoteChildToParent', (payload) => validatePayload(payload, promoteChildToParentDefinition));
