import React, { FunctionComponent, useState, useEffect, Suspense } from 'react';
import { BrowserRouter, Route, Redirect, Switch } from "react-router-dom";
import { useUserProfile } from '../gql/queries/profile';
import { LoggedInContext, getSavedLoggedIn, saveLoggedIn } from '../hooks/useLoggedIn';
import { PrivateRoute } from './PrivateRoute';
import { useKonamiCode } from '../hooks/useKonamiCode';
import { Modal } from './Modal';
import { createClient } from '../util/apollo';
import { ApolloProvider } from '@apollo/client';
import { AppLoader } from './AppLoader';

const LazyHomePage = React.lazy(() => import(/* webpackChunkName: "HomePage" */'./HomePage/HomePage'));
const LazyDashboardPage = React.lazy(() => import(/* webpackChunkName: "DashboardPage" */'./DashboardPage/DashboardPage'));
const LazyUnauthorizedPage = React.lazy(() => import(/* webpackChunkName: "UnauthorizedPage" */'./UnauthorizedPage/UnauthorizedPage'));
const LazyConferencePage = React.lazy(() => import(/* webpackChunkName: "ConferencePage" */'./ConferencePage/ConferencePage'));
const LazyDecisionSupportFilePage = React.lazy(() => import(/* webpackChunkName: "DecisionSupportFilePage" */'./DecisionSupportFilePage/DecisionSupportFilePage'));
const LazyProfilePage = React.lazy(() => import(/* webpackChunkName: "ProfilePage" */'./ProfilePage/ProfilePage'));
const LazyWorkgroupPage = React.lazy(() => import(/* webpackChunkName: "WorkgroupPage" */'./WorkgroupPage/WorkgroupPage'));
const LazyLogoutPage = React.lazy(() => import(/* webpackChunkName: "LogoutPage" */'./LogoutPage'));

export interface AppProps {

}

export const App: FunctionComponent<AppProps> = () => {
  const [ loggedIn, setLoggedIn ] = useState(getSavedLoggedIn());

  const client = createClient((loggedIn) => {
    setLoggedIn(loggedIn);
  });

  useEffect(() => {
    saveLoggedIn(loggedIn);
  }, [loggedIn]);

  const [ showBoneyM, setShowBoneyM ] = useState(false);
  useKonamiCode(() => setShowBoneyM(true));

  return (
    <Suspense fallback={<AppLoader />}>
      <ApolloProvider client={client}>
        <LoggedInContext.Provider value={loggedIn}>
          <UserSessionCheck setLoggedIn={setLoggedIn} />
          <BrowserRouter>
            <Switch>
              <Route path="/" exact component={LazyHomePage} />
              <Route path="/unauthorized" exact component={LazyUnauthorizedPage} />
              <PrivateRoute path="/profile" exact component={LazyProfilePage} />
              <PrivateRoute path="/conference" exact component={LazyConferencePage} />
              <PrivateRoute path="/workgroups/:id" exact component={LazyWorkgroupPage} />
              <PrivateRoute path="/decisions/:id" component={LazyDecisionSupportFilePage} />
              <PrivateRoute path="/dashboard" exact component={LazyDashboardPage} />
              <PrivateRoute path="/logout" exact component={LazyLogoutPage} />
              <Route component={() => <Redirect to="/" />} />
            </Switch>
          </BrowserRouter>
          {
            showBoneyM ?
            <Modal active={true} showCloseButton={true} onClose={() => setShowBoneyM(false)}>
              <iframe width={560} height={315}
                frameBorder={0}
                allowFullScreen={true}
                src="https://www.youtube.com/embed/uVzT5QEEQ2c?autoplay=1" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture">
              </iframe>
            </Modal> :
            null
          }
        </LoggedInContext.Provider>
      </ApolloProvider>
    </Suspense>
  );
}

interface UserSessionCheckProps {
  setLoggedIn: (boolean) => void
}

const UserSessionCheck: FunctionComponent<UserSessionCheckProps> = ({ setLoggedIn }) => {
  const { user, loading } = useUserProfile();

  useEffect(() => {
    if (loading) return;
    setLoggedIn(user && user.id !== '');
  }, [user]);

  return null;
};