import React from 'react';
import { renderHook, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { useGetBulkSessionIngestionQuery } from '../index';
import getBulkSessionIngestionQuery from '../GetBulkSessionIngestion.gql';
import type { GetBulkSessionIngestionQuery } from '../__generated__/GetBulkSessionIngestion';

const mockData: GetBulkSessionIngestionQuery = {
    getBulkSessionIngestion: {
        id: 'ing-1',
        products: [
            {
                id: 'prod-ing-1',
                ingestionStatus: 'success',
                product: {
                    productId: 1001,
                    productName: 'Product One',
                    upc: '123456789012',
                },
            },
        ],
    },
};

describe('useGetBulkSessionIngestionQuery', () => {
    const createWrapper =
        () =>
        ({ children }: any) =>
            (
                <MockedProvider
                    mocks={[
                        {
                            request: {
                                query: getBulkSessionIngestionQuery,
                                variables: { id: 'ing-1' },
                            },
                            result: { data: mockData },
                        },
                    ]}
                >
                    {children}
                </MockedProvider>
            );

    test('returns null data on initial load', () => {
        const { result } = renderHook(
            () => useGetBulkSessionIngestionQuery({ id: 'ing-1' }),
            {
                wrapper: createWrapper(),
            }
        );

        expect(result.current.data).toBeNull();
    });

    test('returns loading state and fetchMore function', () => {
        const { result } = renderHook(
            () => useGetBulkSessionIngestionQuery({ id: 'ing-1' }),
            {
                wrapper: createWrapper(),
            }
        );

        expect(typeof result.current.loading).toBe('boolean');
        expect(typeof result.current.fetchMore).toBe('function');
        expect(typeof result.current.networkStatus).toBe('number');
    });

    test('returns queried data', async () => {
        const { result } = renderHook(
            () => useGetBulkSessionIngestionQuery({ id: 'ing-1' }),
            {
                wrapper: createWrapper(),
            }
        );

        await waitFor(() => {
            expect(result.current.data).toEqual(
                mockData.getBulkSessionIngestion
            );
        });
    });

    test('returns error when query fails', async () => {
        const errorWrapper =
            () =>
            ({ children }: any) =>
                (
                    <MockedProvider
                        mocks={[
                            {
                                request: {
                                    query: getBulkSessionIngestionQuery,
                                    variables: { id: 'ing-1' },
                                },
                                error: new Error('Query failed'),
                            },
                        ]}
                    >
                        {children}
                    </MockedProvider>
                );

        const { result } = renderHook(
            () => useGetBulkSessionIngestionQuery({ id: 'ing-1' }),
            {
                wrapper: errorWrapper(),
            }
        );

        await waitFor(() => {
            expect(result.current.error).toBeDefined();
        });
    });
});
