import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { type RenderResult, render } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { SessionTestProvider } from "@xtablo/shared/contexts/SessionContext";
import { ThemeProvider } from "@xtablo/shared/contexts/ThemeContext";
import React from "react";
import { I18nextProvider } from "react-i18next";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import testI18n from "../i18n.test";

const defaultUser = {
  id: "client-user-1",
  app_metadata: {},
  aud: "test",
  created_at: "2021-01-01",
  email: "client@example.com",
  user_metadata: {
    full_name: "Client User",
  },
};

interface RenderWithProvidersOptions {
  route?: string;
  path?: string;
  language?: string;
  testUser?: typeof defaultUser | undefined;
}

export const renderWithProviders = (
  ui: React.ReactNode,
  options: RenderWithProvidersOptions = {}
): RenderResult & { user: ReturnType<typeof userEvent.setup> } => {
  const { route = "/", path, language = "fr" } = options;
  const testUser = Object.hasOwn(options, "testUser") ? options.testUser : defaultUser;

  testI18n.changeLanguage(language);

  const testQueryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
        staleTime: Infinity,
      },
    },
  });

  const content = path ? (
    <Routes>
      <Route path={path} element={ui} />
    </Routes>
  ) : (
    ui
  );

  return {
    user: userEvent.setup(),
    ...render(
      <I18nextProvider i18n={testI18n}>
        <MemoryRouter initialEntries={[route]}>
          <ThemeProvider>
            <QueryClientProvider client={testQueryClient}>
              <SessionTestProvider testUser={testUser}>{content}</SessionTestProvider>
            </QueryClientProvider>
          </ThemeProvider>
        </MemoryRouter>
      </I18nextProvider>
    ),
  };
};
