import { Suspense, useEffect } from 'react';
import { useNavigate, useRoutes } from 'react-router-dom';

import { PublicClientApplication } from '@azure/msal-browser';
import { MsalProvider } from '@azure/msal-react';
import { GoogleOAuthProvider } from '@react-oauth/google';
import { NuqsAdapter } from 'nuqs/adapters/react-router';
import { AdapterDateFns } from '@material-hu/mui/x-date-pickers/AdapterDateFns';
import { LocalizationProvider } from '@material-hu/mui/x-date-pickers/LocalizationProvider';

import 'src/config/i18n';
import './config/react-pdf';
import '@stream-io/video-react-sdk/dist/css/styles.css';

import api from 'src/config/api';
import { MSAL_CONFIG } from 'src/config/azure';
import { GOOGLE_CONFIG } from 'src/config/google';
import { useAuth } from 'src/contexts/JWTContext';
import { LayoutProvider } from 'src/contexts/LayoutContext';
import { useCDNPing } from 'src/hooks/useCDNPing';
import useScrollReset from 'src/hooks/useScrollReset';
import useTimeInModules from 'src/hooks/useTimeInModules';
import useTimeInScreen from 'src/hooks/useTimeInScreen';
import { EventName } from 'src/types/amplitude';
import { isRedirectError } from 'src/utils/services';

import ErrorBoundary from 'src/components/ErrorBoundary';
import MaintenanceGuard from 'src/components/guards/MaintenanceGuard';
import InactivityTimer from 'src/components/InactivityTimer';
import SplashScreen from 'src/components/SplashScreen';
import ThemedGlobalStyles from 'src/components/ThemedGlobalStyles';

import { initAmplitude } from './config/amplitude';
import { MobileProvider } from './contexts/MobileContext';
import { PostProvider } from './contexts/PostContext';
import { ThemeModeProvider } from './contexts/ThemeModeContext';
import { useHuChatbot } from './hooks/useHuChatbot';
import useTokenManagerHandlers from './hooks/useTokenManagerHandlers';
import { OktaProvider } from './providers/OktaProvider';
import routes from './routes';
import { useLokaliseTranslation } from './utils/i18n';
import { lazyRetry } from './utils/lazyRetry';
import { getCurrentLocale } from './utils/locale';

const NewFeatures = lazyRetry(() =>
  import('src/components/dashboard/initialPopups').then(module => ({
    default: module.NewFeatures,
  })),
);
const TermsAndConditions = lazyRetry(() =>
  import('src/components/dashboard/initialPopups').then(module => ({
    default: module.TermsAndConditions,
  })),
);

const pca = new PublicClientApplication(MSAL_CONFIG);
initAmplitude();

const emptyEventProperties = {};

const App = () => {
  const navigate = useNavigate();
  useLokaliseTranslation(['general', 'validations']);
  const { permissions, isInitialized, isAuthenticated, user } = useAuth();

  const content = useRoutes(routes(permissions, user));

  useScrollReset();
  useTimeInScreen(EventName.USER_APP_USE, emptyEventProperties);
  useTimeInModules();
  useTokenManagerHandlers();
  useCDNPing();
  useHuChatbot();

  useEffect(() => {
    api.interceptors.response.use(
      response => response,
      error => {
        if (!error.config?.skipNotFoundRedirect && isRedirectError(error)) {
          navigate('/');
        }
        return Promise.reject(error);
      },
    );
  }, [navigate]);

  return (
    <LocalizationProvider
      dateAdapter={AdapterDateFns}
      adapterLocale={getCurrentLocale(user)}
    >
      <OktaProvider>
        <MsalProvider instance={pca}>
          <GoogleOAuthProvider clientId={GOOGLE_CONFIG.clientId}>
            <NuqsAdapter>
              <ErrorBoundary>
                <ThemeModeProvider>
                  <MobileProvider>
                    <PostProvider>
                      <ThemedGlobalStyles />
                      <MaintenanceGuard>
                        <LayoutProvider>
                          {isInitialized ? content : <SplashScreen />}
                          {isAuthenticated && (
                            <Suspense fallback={null}>
                              <TermsAndConditions />
                            </Suspense>
                          )}
                          {isAuthenticated && (
                            <Suspense fallback={null}>
                              <NewFeatures />
                            </Suspense>
                          )}
                          <InactivityTimer />
                        </LayoutProvider>
                      </MaintenanceGuard>
                    </PostProvider>
                  </MobileProvider>
                </ThemeModeProvider>
              </ErrorBoundary>
            </NuqsAdapter>
          </GoogleOAuthProvider>
        </MsalProvider>
      </OktaProvider>
    </LocalizationProvider>
  );
};

export default App;
