import { ReactNode, Suspense, lazy, useContext } from 'react';
import {
  Navigate,
  Outlet,
  RouteObject,
  RouterProvider,
  createBrowserRouter,
  useNavigate,
} from 'react-router-dom';

import paths, { rootPaths } from './paths';

import PageLoader from '../components/loading/PageLoader';
import Splash from 'components/loading/Splash';
import Education from 'pages/Education/Education';
import Property from 'pages/Property/Property';
import Vendors from 'pages/Vendors/Vendors';
import EducationDetail from 'components/sections/dashboard/Home/Education/EducationDetail';
import TermsOfService from 'pages/home/TermsOfService';
import { AuthContext, AuthProvider } from 'contexts/AuthContext';
import AmoritizationTable from 'pages/Tools/AmoritizationTable';
import MortgageCalculator from 'pages/Tools/MortgageCalculator';
import HomeAffordability from 'pages/Tools/HomeAffordability';
import Messages from 'pages/Messages/Messages';
import Offers from 'pages/Offers/Offers';
import NetTermsSheet from 'pages/Tools/NetTermsSheet';
import { AccountContext } from 'contexts/AccountContext';
import ProfilePage from 'pages/Profile/Profile';
import Dashboard from 'pages/home/Dashboard';
import PropertyDetailPage from 'pages/Property/PropertyDetailPage';
import PropertySearchPage from 'pages/Property/PropertySearchPage';
import PublicPropertySearch from 'pages/Property/PublicPropertySearch';
import BidsPage from 'pages/Bids/Bids';
import VendorBidsPage from 'components/sections/dashboard/Home/Bids/VendorBids';
import UpgradePage from 'pages/Upgrade/UpgradePage';
import DocumentManager from 'components/sections/dashboard/Home/Documents/DocumentManager';
import { Typography } from '@mui/material';
import PublicPropertyDetail from 'pages/Property/PublicPropertyDetail';
import FAQPage from 'pages/Support/FAQ';
import SupportManager from 'pages/Support/SupportManager';

const RootRedirect = () => {
  const { authenticated } = useContext(AuthContext);

  if (authenticated) {
    return <Navigate to="/dashboard" replace />;
  }

  return <PublicPropertySearch />;
};

const App = lazy(() => import('App'));
const MainLayout = lazy(async () => {
  return Promise.all([
    import('layouts/main-layout'),
    new Promise((resolve) => setTimeout(resolve, 1000)),
  ]).then(([moduleExports]) => moduleExports);
});
const AuthLayout = lazy(async () => {
  return Promise.all([
    import('layouts/auth-layout'),
    new Promise((resolve) => setTimeout(resolve, 1000)),
  ]).then(([moduleExports]) => moduleExports);
});

const PublicLayout = lazy(async () => {
  return Promise.all([
    import('layouts/public-layout'),
    new Promise((resolve) => setTimeout(resolve, 1000)),
  ]).then(([moduleExports]) => moduleExports);
});

const Error404 = lazy(async () => {
  await new Promise((resolve) => setTimeout(resolve, 500));
  return import('pages/errors/Error404');
});

const Login = lazy(async () => import('pages/authentication/Login'));
const SignUp = lazy(async () => import('pages/authentication/SignUp'));

const ResetPassword = lazy(async () => import('pages/authentication/ResetPassword'));
const ForgotPassword = lazy(async () => import('pages/authentication/ForgotPassword'));

type ProtectedRouteProps = {
  children?: ReactNode;
};

const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
  const navigate = useNavigate();
  const { authenticated, loading } = useContext(AuthContext);
  const { account, accountLoading } = useContext(AccountContext);

  if (!loading) {
    if (!authenticated) {
      return <Navigate to="/authentication/login" replace />;
    } else if (!accountLoading && account) {
      console.log(account);
      if (!account.tos_signed) {
        console.log('go to tos');
        //navigate('/terms-of-service');
        return <Navigate to="/terms-of-service" replace />;
      }
    }
  }

  return children;
};

const routes: RouteObject[] = [
  {
    element: (
      <Suspense fallback={<Splash />}>
        <App />
      </Suspense>
    ),
    children: [
      {
        path: rootPaths.dashboardRoot,
        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.dashboard,
            element: <Dashboard />,
          },
        ],
      },
      {
        path: rootPaths.homeRoot,
        element: (
          <PublicLayout>
            <Suspense fallback={<PageLoader />}>
              <Outlet />
            </Suspense>
          </PublicLayout>
        ),
        children: [
          {
            path: paths.publicPropertySearch,
            element: <RootRedirect />,
          },
        ],
      },

      {
        path: rootPaths.publicRoot,
        element: (
          <PublicLayout>
            <Suspense fallback={<PageLoader />}>
              <Outlet />
            </Suspense>
          </PublicLayout>
        ),
        children: [
          {
            path: paths.publicPropertyDetail,
            element: <PublicPropertyDetail />,
          },
        ],
      },
      {
        path: rootPaths.authRoot,
        element: (
          <AuthLayout>
            <Suspense fallback={<PageLoader />}>
              <Outlet />
            </Suspense>
          </AuthLayout>
        ),
        children: [
          {
            path: paths.login,
            element: <Login />,
          },
          {
            path: paths.signup,
            element: <SignUp />,
          },
          {
            path: paths.resetPassword,
            element: <ResetPassword />,
          },
          {
            path: paths.forgotPassword,
            element: <ForgotPassword />,
          },
        ],
      },
      // {
      //     path: rootPaths.termsOfServiceRoot,
      //     element: (
      //       <AuthLayout>
      //       <Suspense fallback={<PageLoader />}>
      //         <Outlet />
      //       </Suspense>
      //     </AuthLayout>
      //     ),
      //   children: [
      //     {
      //       path: paths.login,
      //       element: <TermsOfService />,
      //     },
      //   ]
      // },
      {
        path: rootPaths.propertyRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.property,
            element: <Property />,
          },
          {
            path: paths.propertyDetail,
            element: <PropertyDetailPage />,
          },
        ],
      },
      {
        path: rootPaths.propertySearchRoot,
        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.propertySearch,
            element: <PropertySearchPage />,
          },
        ],
      },
      {
        path: rootPaths.termsOfServiceRoot,
        element: (
          <MainLayout>
            <Suspense fallback={<PageLoader />}>
              <Outlet />
            </Suspense>
          </MainLayout>
        ),
        children: [
          {
            path: paths.termsOfService,
            element: <TermsOfService />,
          },
        ],
      },
      {
        path: rootPaths.educationRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.education,
            element: <Education />,
          },
          {
            path: paths.educationLesson,
            element: <EducationDetail />,
          },
        ],
      },
      {
        path: rootPaths.vendorsRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.vendors,
            element: <Vendors />,
          },
        ],
      },

      {
        path: rootPaths.offersRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.offers,
            element: <Offers />,
          },
        ],
      },
      {
        path: rootPaths.documentsRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.documents,
            element: <DocumentManager />,
          },
        ],
      },
      {
        path: rootPaths.bidsRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.bids,
            element: <BidsPage />,
          },
        ],
      },
      {
        path: rootPaths.vendorBidsRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.vendorBids,
            element: <VendorBidsPage />,
          },
        ],
      },
      {
        path: rootPaths.messageRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.messages,
            element: <Messages />,
          },
        ],
      },
      {
        path: rootPaths.supportRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.support,
            element: <FAQPage />,
          },
          {
            path: paths.supportManager,
            element: <SupportManager />,
          },
        ],
      },
      {
        path: rootPaths.profileRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.profile,
            element: <ProfilePage />,
          },
        ],
      },
      {
        path: rootPaths.upgradeRoot,

        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.upgrade,
            element: <UpgradePage />,
          },
        ],
      },
      {
        path: rootPaths.toolsRoot,
        element: (
          <ProtectedRoute>
            <MainLayout>
              <Suspense fallback={<PageLoader />}>
                <Outlet />
              </Suspense>
            </MainLayout>
          </ProtectedRoute>
        ),
        children: [
          {
            path: paths.homeAffordability,
            element: <HomeAffordability />,
          },
          {
            path: paths.mortageCalculator,
            element: <MortgageCalculator />,
          },
          {
            path: paths.amoritizationTable,
            element: <AmoritizationTable />,
          },
          {
            path: paths.netTermsSheet,
            element: <NetTermsSheet />,
          },
        ],
      },
      {
        path: '*',
        element: <Error404 />,
      },
    ],
  },
];

const router = createBrowserRouter(routes, { basename: '' });

export default router;
