/**
 *  @author: Hemal
 * File: contactUs.test.ts
 * Purpose: This file contains unit tests for the `contactUs` asynchronous thunk action.
 * Description:
 * - Utilizes `jest.mock` to mock the `apiClient` module.
 * - Tests the behavior of the `contactUs` action, including dispatching actions and handling API responses.
 * - Verifies that the correct actions are dispatched based on the API response.
 */

jest.mock('../../src/interceptor/apiClient');

import { API_ENDPOINTS } from '@/src/utils/commonVariables';
import apiClient from '../../src/interceptor/apiClient';
import { ContactUsPayload } from '@/redux/types/contactUsType';
const mockedApi = apiClient as jest.Mocked<typeof apiClient>;

describe('contactUs thunk', () => {
    const mockDispatch = jest.fn();

    /**
     * Asynchronous thunk action to send contact form data to the API.
     * Dispatches different Redux actions based on the API response.
     * 
     * @param payload - The data from the contact form.
     * @param callback - Optional callback function that receives the API response data.
     * 
     * Dispatches:
     * - REQUEST_CONTACT_US: Before the API call to indicate loading.
     * - SUCCESS_CONTACT_US: On successful API response.
     * - ERROR_CONTACT_US: On API error.
     */

    const contactUs = (payload: ContactUsPayload, callback?: (data: any) => void) => async (dispatch: any) => {
        dispatch({ type: 'REQUEST_CONTACT_US' });
        try {
            const response = await apiClient.post(API_ENDPOINTS.CONTACT_US, payload);
            dispatch({ type: 'SUCCESS_CONTACT_US', payload: response.data });
            callback && callback(response.data);
        } catch (error) {
            dispatch({ type: 'ERROR_CONTACT_US' });
        }
    };

    // Mock response data
    const mockResponseData = {
        meta: {
            status: 1,
            message: 'Message received successfully.'
        },
        data: {
            contactId: '12345'
        }
    };

    // Clear mocks before each test
    beforeEach(() => {
        jest.clearAllMocks();
    });

    // Test case for successful contact form submission with callback
    it('should dispatch success actions and invoke callback on success', async () => {
        mockedApi.post.mockResolvedValueOnce({ data: mockResponseData });

        const payload = {
            firstName: 'John Doe',
            lastName: "Doe",
            email: 'john@example.com',
            message: 'Test message',
            mobileNumber: '1234567890',
            countryCode: 'AT'
        };

        const callback = jest.fn();

        await contactUs(payload, callback)(mockDispatch);

        expect(mockedApi.post).toHaveBeenCalledWith(API_ENDPOINTS.CONTACT_US, payload);
        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_CONTACT_US' });
        expect(mockDispatch).toHaveBeenCalledWith({
            type: 'SUCCESS_CONTACT_US',
            payload: mockResponseData
        });
        expect(callback).toHaveBeenCalledWith(mockResponseData);
    });

    // Test case for API failure
    it('should dispatch failure action on API error', async () => {
        mockedApi.post.mockRejectedValueOnce(new Error('API failure'));

        const payload = {
            firstName: 'John Doe',
            lastName: "Doe",
            email: 'john@example.com',
            message: 'Test message',
            mobileNumber: '1234567890',
            countryCode: 'AT'
        };

        await contactUs(payload)(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_CONTACT_US' });
        expect(mockDispatch).toHaveBeenCalledWith({ type: 'ERROR_CONTACT_US' });
    });
});
