import type { ReactElement, ReactNode } from 'react'
import { render, type RenderOptions, type RenderResult } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import { I18nextProvider } from 'react-i18next'
import i18n from '../../src/i18n'
import { AuthProvider } from '../../src/auth'

export interface RenderWithProvidersOptions extends RenderOptions {
  /** Initial route(s) for the in-memory router. Defaults to ['/']. */
  initialEntries?: string[]
  /** Initial entry index. Defaults to 0. */
  initialIndex?: number
  /** Skip wrapping in <AuthProvider>. Useful for tests that mock auth themselves. */
  withoutAuth?: boolean
  /** Skip wrapping in <I18nextProvider>. */
  withoutI18n?: boolean
}

export function renderWithProviders(
  ui: ReactElement,
  {
    initialEntries = ['/'],
    initialIndex = 0,
    withoutAuth,
    withoutI18n,
    ...rtl
  }: RenderWithProvidersOptions = {},
): RenderResult {
  const Wrapper = ({ children }: { children: ReactNode }) => {
    let tree = <MemoryRouter initialEntries={initialEntries} initialIndex={initialIndex}>{children}</MemoryRouter>
    if (!withoutAuth) tree = <AuthProvider>{tree}</AuthProvider>
    if (!withoutI18n) tree = <I18nextProvider i18n={i18n}>{tree}</I18nextProvider>
    return tree
  }
  return render(ui, { wrapper: Wrapper, ...rtl })
}

export { screen, within, fireEvent, waitFor, act } from '@testing-library/react'
export { default as userEvent } from '@testing-library/user-event'
