// src/tests/utils/renderWithProviders.tsx
import React, { ReactElement, ReactNode } from 'react';
import { render, RenderOptions } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { MemoryRouter } from 'react-router-dom';
import { AuthProvider } from '../../providers/AuthProvider';
import { FlyersProvider } from '../../providers/FlyersProvider';
import { MasterItemsProvider } from '../../providers/MasterItemsProvider';
import { ModalProvider } from '../../providers/ModalProvider';
import { UserDataProvider } from '../../providers/UserDataProvider';

/**
 * Creates a fresh QueryClient configured for testing.
 * Uses minimal retry/cache settings to make tests faster and more predictable.
 *
 * @returns A new QueryClient instance for testing
 */
export const createTestQueryClient = () =>
  new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        gcTime: 0,
        staleTime: 0,
      },
      mutations: {
        retry: false,
      },
    },
  });

/**
 * A wrapper component that provides just the QueryClientProvider.
 * Use this for testing hooks or components that use TanStack Query but don't
 * need the full AppProviders stack.
 */
export const QueryWrapper = ({ children }: { children: ReactNode }) => {
  const testQueryClient = createTestQueryClient();
  return <QueryClientProvider client={testQueryClient}>{children}</QueryClientProvider>;
};

interface ExtendedRenderOptions extends Omit<RenderOptions, 'wrapper'> {
  initialEntries?: string[];
}

/**
 * A custom render function that wraps the component with all application providers.
 * This is useful for testing components that rely on context values (Auth, Modal, etc.).
 *
 * Unlike AppProviders, this uses a fresh test-specific QueryClient for each render
 * to ensure test isolation and predictable behavior (no retries, no caching).
 *
 * @param ui The component to render
 * @param options Additional render options
 * @returns The result of the render function
 */
export const renderWithProviders = (ui: ReactElement, options?: ExtendedRenderOptions) => {
  const { initialEntries, ...renderOptions } = options || {};
  const testQueryClient = createTestQueryClient();
  // Replicate the AppProviders hierarchy but with a test-specific QueryClient
  const Wrapper = ({ children }: { children: React.ReactNode }) => (
    <MemoryRouter initialEntries={initialEntries}>
      <QueryClientProvider client={testQueryClient}>
        <ModalProvider>
          <AuthProvider>
            <FlyersProvider>
              <MasterItemsProvider>
                <UserDataProvider>{children}</UserDataProvider>
              </MasterItemsProvider>
            </FlyersProvider>
          </AuthProvider>
        </ModalProvider>
      </QueryClientProvider>
    </MemoryRouter>
  );
  return render(ui, { wrapper: Wrapper, ...renderOptions });
};
