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('getPaymentDetailsList thunk', () => {
    const mockDispatch = jest.fn();
    const mockCallback = jest.fn();

    // Inline thunk definition
    const getPaymentDetailsList =
        (payload: { page: number; perPage: number }, callback?: (data: any) => void) =>
            async (dispatch: any) => {
                try {
                    dispatch({ type: 'REQUEST_PAYMENT_DETAILS_LIST' });
                    const response: any = await apiClient.post(API_ENDPOINTS.PAYMENT_DETAILS_LIST, payload);

                    if (response?.data?.meta?.status === 0) {
                        // Skipping Toast
                    } else {
                        callback && callback(response?.data);
                    }

                    dispatch({ type: 'SUCCESS_PAYMENT_DETAILS_LIST', payload: response?.data });
                } catch (error: any) {
                    dispatch({ type: 'FAILURE_PAYMENT_DETAILS_LIST' });
                    // Skipping Toast
                }
            };

    const mockSuccessResponse = {
        data: {
            meta: {
                status: 1,
                message: 'Payment details fetched successfully',
            },
            data: {
                payments: [{ id: 'pay-001', amount: 100 }],
                total: 1,
            },
        },
    };

    const mockHandledErrorResponse = {
        data: {
            meta: {
                status: 0,
                message: 'Invalid filters',
            },
        },
    };

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

    it('should dispatch success and call callback when meta.status is 1', async () => {
        mockedApi.post.mockResolvedValueOnce(mockSuccessResponse);

        const payload = { page: 1, perPage: 10 };

        await getPaymentDetailsList(payload, mockCallback)(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_PAYMENT_DETAILS_LIST' });
        expect(mockedApi.post).toHaveBeenCalledWith(API_ENDPOINTS.PAYMENT_DETAILS_LIST, payload);
        expect(mockCallback).toHaveBeenCalledWith(mockSuccessResponse.data);
        expect(mockDispatch).toHaveBeenCalledWith({
            type: 'SUCCESS_PAYMENT_DETAILS_LIST',
            payload: mockSuccessResponse.data,
        });
    });

    it('should dispatch success but not call callback when meta.status is 0', async () => {
        mockedApi.post.mockResolvedValueOnce(mockHandledErrorResponse);

        const payload = { page: 1, perPage: 10 };

        await getPaymentDetailsList(payload, mockCallback)(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_PAYMENT_DETAILS_LIST' });
        expect(mockCallback).not.toHaveBeenCalled();
        expect(mockDispatch).toHaveBeenCalledWith({
            type: 'SUCCESS_PAYMENT_DETAILS_LIST',
            payload: mockHandledErrorResponse.data,
        });
    });

    it('should dispatch failure on API error', async () => {
        mockedApi.post.mockRejectedValueOnce(new Error('Server error'));

        const payload = { page: 1, perPage: 10 };

        await getPaymentDetailsList(payload, mockCallback)(mockDispatch);

        expect(mockDispatch).toHaveBeenCalledWith({ type: 'REQUEST_PAYMENT_DETAILS_LIST' });
        expect(mockDispatch).toHaveBeenCalledWith({ type: 'FAILURE_PAYMENT_DETAILS_LIST' });
        expect(mockCallback).not.toHaveBeenCalled();
    });
});
