import { useEffect, Suspense } from 'react';

import 'dayjs/locale/en';
import 'dayjs/locale/pt';
import 'dayjs/locale/fr';
import 'dayjs/locale/es';
import dayjs from 'dayjs';
import timezonePlugin from 'dayjs/plugin/timezone';
import utcPlugin from 'dayjs/plugin/utc';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
import weekday from 'dayjs/plugin/weekday';
import isBetween from 'dayjs/plugin/isBetween';
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import duration from 'dayjs/plugin/duration';
import { and, equals, isNil, not } from 'ramda';
import { Outlet, useLocation } from 'react-router-dom';
import { useAtomValue, useAtom } from 'jotai';

import reactRoutes from '../reactRoutes/routeMap';

import { platformInstallationStatusAtom } from './atoms/platformInstallationStatusAtom';
import { MainLoaderWithoutTranslation } from './MainLoader';
import useMain, { router } from './useMain';
import { areUserParametersLoadedAtom } from './useUser';

dayjs.extend(localizedFormat);
dayjs.extend(utcPlugin);
dayjs.extend(timezonePlugin);
dayjs.extend(isToday);
dayjs.extend(isYesterday);
dayjs.extend(weekday);
dayjs.extend(isBetween);
dayjs.extend(isSameOrBefore);
dayjs.extend(duration);

const Main = (): JSX.Element => {
  const navigate = router.useNavigate();
  const { pathname } = useLocation();

  useMain();

  const [areUserParametersLoaded] = useAtom(areUserParametersLoadedAtom);
  const platformInstallationStatus = useAtomValue(
    platformInstallationStatusAtom
  );

  const navigateTo = (path: string): void => {
    navigate(path);
    window.location.reload();
  };

  useEffect(() => {
    if (isNil(platformInstallationStatus) || isNil(areUserParametersLoaded)) {
      return;
    }

    if (not(platformInstallationStatus.isInstalled)) {
      navigateTo(reactRoutes.install);

      return;
    }

    const canUpgrade = and(
      platformInstallationStatus.hasUpgradeAvailable,
      not(areUserParametersLoaded)
    );

    if (canUpgrade) {
      navigateTo(reactRoutes.upgrade);

      return;
    }

    if (
      not(areUserParametersLoaded) &&
      !equals(pathname, reactRoutes.authenticationDenied) &&
      !equals(pathname, reactRoutes.logout) &&
      !equals(pathname, reactRoutes.login)
    ) {
      navigate(reactRoutes.login);
    }
  }, [platformInstallationStatus, areUserParametersLoaded]);

  if (isNil(platformInstallationStatus)) {
    return <MainLoaderWithoutTranslation />;
  }

  return (
    <Suspense fallback={<MainLoaderWithoutTranslation />}>
      <Outlet />
    </Suspense>
  );
};

export default Main;
