import { 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 { buildPaginatedCommerceAPIRequest, } from '../common/paginated-commerce-api-request-builder.js';
import { getProductsFromCartPurchasedState } from '../context/cart/cart-state.js';
import { perPageRecommendationSelector } from '../pagination/pagination-selectors.js';
import { recommendationsSlotDefinition } from './recommendations.js';
import { moreRecommendationsAvailableSelector, numberOfRecommendationsSelector, } from './recommendations-selectors.js';
const buildRecommendationCommerceAPIRequest = (slotId, state, navigatorContext, productId) => {
    const commerceAPIRequest = buildPaginatedCommerceAPIRequest(state, navigatorContext, slotId);
    return {
        ...commerceAPIRequest,
        context: {
            ...commerceAPIRequest.context,
            ...(productId ? { product: { productId } } : {}),
            purchased: getProductsFromCartPurchasedState(state.cart),
        },
        slotId,
    };
};
export const fetchRecommendations = createAsyncThunk('commerce/recommendations/fetch', async (payload, { getState, rejectWithValue, extra: { apiClient, navigatorContext } }) => {
    const { slotId, productId } = payload;
    const request = buildRecommendationCommerceAPIRequest(slotId, getState(), navigatorContext, productId);
    const fetched = await apiClient.getRecommendations(request);
    if (isErrorResponse(fetched)) {
        return rejectWithValue(fetched.error);
    }
    return {
        response: fetched.success,
    };
});
export const fetchMoreRecommendations = createAsyncThunk('commerce/recommendations/fetchMore', async (payload, { getState, rejectWithValue, extra: { apiClient, navigatorContext } }) => {
    const slotId = payload.slotId;
    const state = getState();
    const moreRecommendationsAvailable = moreRecommendationsAvailableSelector(state, slotId);
    if (!moreRecommendationsAvailable === false) {
        return null;
    }
    const perPage = perPageRecommendationSelector(state, slotId);
    const numberOfProducts = numberOfRecommendationsSelector(state, slotId);
    const nextPageToRequest = numberOfProducts / perPage;
    const request = {
        ...buildRecommendationCommerceAPIRequest(slotId, state, navigatorContext),
        page: nextPageToRequest,
    };
    const fetched = await apiClient.getRecommendations(request);
    if (isErrorResponse(fetched)) {
        return rejectWithValue(fetched.error);
    }
    return {
        response: fetched.success,
    };
});
export const registerRecommendationsSlot = createAction('commerce/recommendations/registerSlot', (payload) => validatePayload(payload, recommendationsSlotDefinition));
export const promoteChildToParentDefinition = {
    child: new RecordValue({
        options: { required: true },
        values: {
            permanentid: new StringValue({ required: true }),
        },
    }),
    ...recommendationsSlotDefinition,
};
export const promoteChildToParent = createAction('commerce/recommendations/promoteChildToParent', (payload) => validatePayload(payload, promoteChildToParentDefinition));
