/**
 * @author: Hemal
 * File: getFiltersList.test.ts
 * Purpose: Unit tests for the `getFiltersList` asynchronous thunk action.
 * Description:
 * - Mocks `apiClient` using Jest.
 * - Verifies correct actions dispatched on API success and failure.
 * - Uses plain action objects instead of propertyActions or Toast.
 */

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

import apiClient from '../../src/interceptor/apiClient';
import { API_ENDPOINTS } from '@/src/utils/commonVariables';

const mockedApi = apiClient as jest.Mocked<typeof apiClient>;

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

    /**
     * Thunk to get filters list.
     */
    const getFiltersList = () => async (dispatch: any) => {
        try {
            dispatch({ type: 'REQUEST_FILTERS_LIST' });
            const { data } = await apiClient.post(API_ENDPOINTS.LIST_FILTERS);
            dispatch({
                type: 'SUCCESS_FILTERS_LIST',
                payload: data?.data,
            });
        } catch (error) {
            dispatch({ type: 'FAILURE_FILTERS_LIST' });
        }
    };

    const mockResponseData = {
        data: {
            statusCode: 200,
            data: {
                bathroom: [{
                    amenitiesId: "b3320180-0339-4cea-bd2a-c3e3d41cd21a",
                    title: "Bathtub",
                    slug: "bathtub"
                }],
                bedType: [{
                    amenitiesId: "7acc5f1a-15ea-41e2-819a-fcc6d2e0098d",
                    title: "King",
                    slug: "king"
                }],
                homebase: [{
                    amenitiesId: "0f72f755-1cbc-4f94-bf94-ac42b7dea0fc",
                    title: "Air conditioning",
                    slug: "air-conditioning"
                }],
                location: [{
                    amenitiesId: "fc5eeaa7-a436-41a6-877c-ee699862e887",
                    title: "Beach",
                    slug: "beach"
                }],
                propertyMaximumDuration: {
                    number: 5,
                    duration: "weeks"
                },
                propertyMaximumPrice: {
                    price: 72,
                    currency: "EUR",
                    currencySymbol: "€"
                },
                propertyMinimumDuration: {
                    number: "1",
                    duration: "weeks"
                },
                propertyMinimumPrice: {
                    price: 0,
                    currency: "EUR",
                    currencySymbol: "€"
                },
                propertySortBy: [{
                    title: "Newest Listings",
                    slug: "newest-listings"
                }],
                propertyStatus: [{
                    title: "Published",
                    slug: "published"
                }],
                propertyTypes: [{
                    propertyTypeId: "2e6665e1-7e6a-4535-8112-3dc2ca8dd1e9",
                    title: "Room",
                    description: "A private bedroom with a shared communal space.",
                    slug: "room",
                    icon: 'https://dummyicon.com/room-icon.svg',
                    propertyFeatures: [],
                    selectedIcon: "https://dummyicon.com/room-selected-icon.svg",
                    listingIcon: "https://dummyicon.com/room-listing-icon.svg",
                    status: 1,
                    createdAt: "1750317909569",
                    updatedAt: "1750317909369"
                }],
                workspace: [{
                    amenitiesId: "a29a2dea-d5c8-4fae-93d1-738ecf47b48c",
                    title: "Computer",
                    slug: "computer"
                }]
            },
            meta: { status: 1, message: 'Property filters fetched successfully' },
        },
    };

    beforeEach(() => {
        jest.clearAllMocks();
    });

    //Success case
    it('should dispatch success actions on successful API response', async () => {
        mockedApi.post.mockResolvedValueOnce(mockResponseData);

        await getFiltersList()(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_FILTERS_LIST' });
        expect(mockedApi.post).toHaveBeenCalledWith(API_ENDPOINTS.LIST_FILTERS);
        expect(mockDispatch).toHaveBeenCalledWith({
            type: 'SUCCESS_FILTERS_LIST',
            payload: mockResponseData.data.data,
        });
    });

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

        await getFiltersList()(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_FILTERS_LIST' });
        expect(mockDispatch).toHaveBeenCalledWith({ type: 'FAILURE_FILTERS_LIST' });
    });
});
