import { render } from '@testing-library/react';
import * as React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { renderHook } from '@testing-library/react-hooks';
import { WrapperComponent } from '@testing-library/react-hooks/src/types/react';

function createTestQueryClient() {
  return new QueryClient({
    defaultOptions: {
      queries: {
        retry: false
      }
    }
  });
}

export function renderWithClient(
  ui: React.ReactElement,
  wrapper?: React.JSXElementConstructor<{ children: React.ReactElement }>
) {
  const testQueryClient = createTestQueryClient();
  const { rerender, ...result } = render(
    <QueryClientProvider client={testQueryClient}>{ui}</QueryClientProvider>,
    {
      wrapper
    }
  );
  return {
    ...result,
    rerender: (rerenderUi: React.ReactElement) =>
      rerender(<QueryClientProvider client={testQueryClient}>{rerenderUi}</QueryClientProvider>)
  };
}

type WrapperProps = { children: React.ReactNode };

export function createQueryClientWrapper(): WrapperComponent<WrapperProps> {
  const testQueryClient = createTestQueryClient();
  // eslint-disable-next-line react/display-name
  return ({ children }: WrapperProps) => (
    <QueryClientProvider client={testQueryClient}>{children}</QueryClientProvider>
  );
}

export function renderHookWithQueryClientWrapper<TResult>(
  callback: (props: WrapperProps) => TResult
) {
  return renderHook(callback, {
    wrapper: createQueryClientWrapper()
  });
}
