import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createRouter } from '@tanstack/react-router';
import { HTTPError } from 'ky';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { isValidationErrorLike, isZodErrorLike } from 'zod-validation-error';

import '@/index.css';
import { CACHE_DURATION } from '@/configs/time';
import { RETRY_STATUS_CODES } from '@/lib/api/config';
import { logger } from '@/lib/logger/app-logger';
import { RouterWithContext } from '@/router-provider';
import '@/stores/devtools';
import { routeTree } from './routeTree.gen';

declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router;
  }
}

export const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: CACHE_DURATION.TWO_MINUTES,
      retry(failureCount, error) {
        logger.info('[QUERY] Retry attempt', {
          domain: 'query',
          event: 'retry_attempt',
          failureCount,
          errorMessage:
            error instanceof Error ? error.message : 'Unknown error',
          errorType:
            error instanceof HTTPError
              ? 'HTTP'
              : isZodErrorLike(error)
                ? 'Validation'
                : isValidationErrorLike(error)
                  ? 'Validation'
                  : 'Generic',
        });

        if (error instanceof HTTPError) {
          if (
            !RETRY_STATUS_CODES.includes(
              error.response.status as (typeof RETRY_STATUS_CODES)[number],
            )
          ) {
            return false;
          }
        }

        if (isZodErrorLike(error) || isValidationErrorLike(error)) {
          return false;
        }

        return failureCount < 3;
      },
    },
  },
});

export const router = createRouter({
  routeTree,
  defaultPreload: 'intent',
  defaultPreloadStaleTime: CACHE_DURATION.TWO_MINUTES,
  scrollRestoration: true,
  context: {
    auth: undefined!,
    queryClient,
  },
});

if (import.meta.env.DEV && import.meta.env.VITE_USE_MSW === 'true') {
  import('./mocks/browser').then(({ worker }) => {
    worker.start({
      onUnhandledRequest: 'bypass',
    });
  });
}

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <QueryClientProvider client={queryClient}>
      <RouterWithContext />
    </QueryClientProvider>
  </StrictMode>,
);
