import { type FC } from 'react'
import '@/assets/fonts/irancell/style.css'
import 'swiper/swiper-bundle.css';
import 'react-loading-skeleton/dist/skeleton.css'
import { BrowserRouter } from 'react-router-dom'
import { QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'
import MainRouter from './router/MainRouter'
import ToastContainer from './components/Toast'
import { getRefreshToken, setRefreshToken, setToken } from './config/func';
import AuthRouter from './router/AuthRouter';
import CompleteProfileRouter from './router/CompleteProfileRouter';
import type { IApiErrorRepsonse } from './shared/types/Types';
import { Paths } from './config/Paths';
import { useSessionAuth } from './config/sessionAuth';
import { appNavigate, AppNavigation } from './config/navigation';
import { refreshToken } from './pages/auth/service/AuthService';
import { useGetMe } from './pages/user/hooks/useUserData';
import { needsProfileCompletion } from './pages/user/utils/profileUtils';
import MoonLoader from 'react-spinners/MoonLoader';

declare global {
  interface Window {
    isRefreshingToken?: boolean;
    isRefreshTokenExpired?: boolean;
  }
}

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: async (error: IApiErrorRepsonse) => {
      if (error?.response?.status === 401) {
        // اگر refresh token منقضی شده باشد، دیگر تلاش نکن
        if (window.isRefreshTokenExpired) {
          return;
        }

        // بررسی کن که آیا خطا از refresh endpoint است
        const isRefreshEndpoint = error?.config?.url?.includes('/public/auth/refresh');

        // اگر خطا از refresh endpoint است، refresh token منقضی شده
        if (isRefreshEndpoint) {
          window.isRefreshTokenExpired = true;
          useSessionAuth.getState().clearSession();
          queryClient.clear();
          appNavigate(Paths.auth.login, { replace: true });
          return;
        }

        try {
          // Use a flag to track if refresh is in progress
          if (window.isRefreshingToken) {
            // Wait for the refresh to complete
            await new Promise(resolve => {
              const checkComplete = setInterval(() => {
                if (!window.isRefreshingToken) {
                  clearInterval(checkComplete);
                  resolve(true);
                }
              }, 100);
            });
            return;
          }

          // Set the flag to indicate refresh is in progress
          window.isRefreshingToken = true;

          try {
            const refreshTokenValue = await getRefreshToken();

            if (!refreshTokenValue) {
              window.isRefreshTokenExpired = true;
              useSessionAuth.getState().clearSession();
              queryClient.clear();
              appNavigate(Paths.auth.login, { replace: true });
              return;
            }

            const { data } = await refreshToken({ refreshToken: refreshTokenValue || '' });

            if (data?.accessToken?.token) {
              // Save the new token
              await setToken(data?.accessToken?.token);

              // If refresh token also returned, update it
              if (data.refreshToken?.token) {
                await setRefreshToken(data.refreshToken?.token);
              }

              // Reset expired flag if refresh was successful
              window.isRefreshTokenExpired = false;

              // Retry the failed request
              queryClient.invalidateQueries();
              return;
            } else {
              throw new Error('Invalid token response');
            }
          } finally {
            window.isRefreshingToken = false;
          }
        } catch (refreshError: unknown) {
          console.error('Token refresh failed:', refreshError);

          // بررسی کن که آیا خطا از refresh endpoint است
          const errorWithConfig = refreshError as IApiErrorRepsonse;
          const isRefreshError = errorWithConfig?.config?.url?.includes('/admin/auth/refresh');

          // اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن
          if (isRefreshError || errorWithConfig?.response?.statusCode === 401) {
            window.isRefreshTokenExpired = true;
          }

          useSessionAuth.getState().clearSession();
          queryClient.clear();
          appNavigate(Paths.auth.login, { replace: true });
        }
      }
    }
  }),
  defaultOptions: {
    queries: {
      refetchOnWindowFocus: false,
      retry: false
      // staleTime: 86400000 // 1 day in milliseconds
    }
  }
});

const AppRoutes: FC = () => {
  const isLoggedIn = useSessionAuth((state) => state.isAuthenticated)
  const { data: user, isLoading } = useGetMe({ enabled: isLoggedIn })
  const profileIncomplete = isLoggedIn && needsProfileCompletion(user)

  if (isLoggedIn && isLoading) {
    return (
      <div className='w-full h-screen flex items-center justify-center'>
        <MoonLoader size={32} color='#000' />
      </div>
    )
  }

  return (
    <BrowserRouter>
      <AppNavigation />
      {!isLoggedIn ? (
        <AuthRouter />
      ) : profileIncomplete ? (
        <CompleteProfileRouter />
      ) : (
        <MainRouter />
      )}
      <ToastContainer />
    </BrowserRouter>
  )
}

const App: FC = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <AppRoutes />
    </QueryClientProvider>
  )
}

export default App