import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render } from '@testing-library/react'
import { createContext, useContext, useState } from 'react'
import { HelmetProvider } from 'react-helmet-async'
import { createMemoryRouter, RouterProvider } from 'react-router-dom'

import DialogueProvider from '@/components/dialogues/DialogueProvider'
import { KeyboardShortcutsProvider } from '@/lib/useKeyboardShortcuts'
import { UnsavedChangesGuardProvider } from '@/lib/useUnsavedChangesGuard'

import type { ReactElement, ReactNode } from 'react'

type Options = {
  route?: string
}

const TestContentContext = createContext<ReactNode> (null)


const TestRoute = () => {
  const children = useContext (TestContentContext)

  return (
      <UnsavedChangesGuardProvider>
        <KeyboardShortcutsProvider>
          {children}
        </KeyboardShortcutsProvider>
      </UnsavedChangesGuardProvider>)
}

export const renderWithProviders = (
    ui:       ReactElement,
    options: Options = {},
) => {
  const queryClient = new QueryClient ({
    defaultOptions: {
      queries: { retry: false } },
  })

  const Wrapper = ({ children }: { children: ReactNode }) => {
    const [router] = useState (() => createMemoryRouter ([{
        path: '*',
        element: <TestRoute/> }], {
        initialEntries: [options.route ?? '/'] }))

    return (
	<QueryClientProvider client={queryClient}>
	  <HelmetProvider>
	    <DialogueProvider>
	      <TestContentContext.Provider value={children}>
		<RouterProvider router={router}/>
	      </TestContentContext.Provider>
	    </DialogueProvider>
	  </HelmetProvider>
	</QueryClientProvider>)
  }

  return {
    queryClient,
    ...render (ui, { wrapper: Wrapper }) }
}
