import React, { Suspense } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { KeycloakProvider } from "@react-keycloak/web";
import * as Sentry from "@sentry/react";

import { loadGroupMappings } from "actions/misc";
import { loadProgram } from "actions/program";
import Footer from "components/Footer";
import Navbar from "components/Navbar";
import Home from "pages/Home";
import Program from "pages/Program";
import { AuthStore } from "stores";

import keycloak from "./keycloak";

/**
 * If configured, set up Sentry client that reports uncaught errors down to
 * https://sentry.io.
 */
if (process.env.REACT_APP_SENTRY_DSN) {
  Sentry.init({
    dsn: process.env.REACT_APP_SENTRY_DSN,
    tracesSampleRate: 0.1,
  });
}

const onKeycloakEvent = (event) => {
  if (["onAuthRefreshSuccess", "onAuthSuccess"].includes(event)) {
    Sentry.setUser(keycloak.tokenParsed);
    AuthStore.update((state) => {
      state.isAuthenticated = true;
      state.user = {
        name: keycloak.tokenParsed.name,
        username: keycloak.tokenParsed.preferred_username,
        groups: keycloak.tokenParsed.groups,
        accessToken: keycloak.token,
      };
    });
  }
};

const LoadingComponent = (
  <div className="h-screen w-screen flex justify-center items-center">
    <div className="text-center">
      <div className="flex flex-col md:flex-row items-center space-x-4 text-center mb-2 md:mb-4">
        <img
          src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-black.svg`}
          className="w-16 mb-2"
          alt="Pirátská strana"
        />
        <h1 className="head-alt-md md:head-alt-lg">Celostátní fórum 2021</h1>
      </div>
      <p className="text-center">Načítám aplikaci ...</p>
    </div>
  </div>
);

const BaseApp = () => {
  loadGroupMappings.read();
  loadProgram.read();

  return (
    <Router>
      <Navbar />
      <Switch>
        <Route exact path="/" children={<Home />} />
        <Route exact path="/program" children={<Program />} />
      </Switch>
      <Footer />
    </Router>
  );
};

const AuthenticatedApp = () => {
  const keycloakInitConfig = {
    onLoad: "check-sso",
    // Necessary to prevent Keycloak cookie issues:
    // @see: https://stackoverflow.com/a/63588334/303184
    checkLoginIframe: false,
  };

  return (
    <>
      <KeycloakProvider
        keycloak={keycloak}
        initConfig={keycloakInitConfig}
        LoadingComponent={LoadingComponent}
        onEvent={onKeycloakEvent}
      >
        <Suspense fallback={LoadingComponent}>
          <BaseApp />
        </Suspense>
      </KeycloakProvider>
    </>
  );
};

const ErrorBoundaryFallback = ({ error }) => {
  return (
    <div className="h-screen w-screen flex justify-center items-center">
      <div className="text-center">
        <h1 className="head-alt-xl text-red-600 mb-4">
          V aplikaci došlo k chybě :(
        </h1>
        <p className="text-lg leading-normal">
          Naši vývojáři o tom již byli informování a opraví to co nejdříve.
          <br />
          Omlouváme se za tuto nepříjemnost.
        </p>
        <a href="/" className="btn mt-8">
          <div className="btn__body">Načíst znovu</div>
        </a>
      </div>
    </div>
  );
};

const App = Sentry.withProfiler(() => {
  return (
    <Sentry.ErrorBoundary fallback={ErrorBoundaryFallback} showDialog>
      <AuthenticatedApp />
    </Sentry.ErrorBoundary>
  );
});

export default App;