/* @aztlan/generator-front 3.1.2 */
import * as React from 'react'
import { HelmetProvider } from 'react-helmet-async'
import { IntlProvider } from 'react-intl'
import {
  RelayEnvironmentProvider, graphql,
} from 'react-relay'
import * as PropTypes from 'prop-types'
import { InferProps } from 'prop-types'
import {
  StaticRouter, BrowserRouter,
} from 'react-router-dom'

import {
  ApplicationProvider,
  useApplicationContext,
  AuthenticationProvider,
  SwitchRoutes,
} from '@aztlan/ui'

// const baseClassName = styleNames.base
// const componentClassName = 'application'

function ThemeWrapper({ children }) {
  const { theme } = useApplicationContext()
  return <main className={`${theme || ''} background far`}>{children}</main>
}

ThemeWrapper.propTypes = { children: PropTypes.any }
/**
 * description
 * @param {InferProps<typeof Application.propTypes>} props -
 * @returns {React.ReactElement} - Rendered Application
 */
function Application({
  // Non Isomorphic props
  locale,
  localeProps,
  messages,
  relayEnvironment,
  ssrHelmetContext,
  ssrHostname,
  ssrLocation,
  ssrRouterContext,
  // Isomorphic props
  routes,
  prefetchRoutes,
  maintenance,
  QUERY_APPLICATION,
  applicationQueryVariables,
  defaultRedirectionAfterLogin,
  MUTATION_LOGOUT,
  FRAGMENT_VIEWER,
  Status404Page,
  loginPath,
}: InferProps<typeof Application.propTypes>) {
  const Router = ssrLocation ? StaticRouter : BrowserRouter
  return (
    <RelayEnvironmentProvider environment={relayEnvironment}>
      <Router
        location={ssrLocation}
        routerContext={ssrRouterContext}
      >
        <IntlProvider
          locale={locale}
          messages={messages}
        >
          <HelmetProvider context={ssrHelmetContext}>
            <ApplicationProvider
              value={{
                locale,
                ...localeProps,
              }}
              routes={prefetchRoutes || routes}
              maintenance={maintenance}
              ssrHostname={ssrHostname}
              QUERY_APPLICATION={QUERY_APPLICATION}
              applicationQueryVariables={applicationQueryVariables}
              defaultRedirectionAfterLogin={defaultRedirectionAfterLogin}
            >
              <AuthenticationProvider
                FRAGMENT_VIEWER={FRAGMENT_VIEWER}
                MUTATION_LOGOUT={MUTATION_LOGOUT}
                loginPath={loginPath}
              >
                <ThemeWrapper>
                  <SwitchRoutes
                    items={routes}
                    NotFoundPage={Status404Page}
                    // wireframe={wireframe}
                  />
                </ThemeWrapper>
              </AuthenticationProvider>
            </ApplicationProvider>
          </HelmetProvider>
        </IntlProvider>
      </Router>
    </RelayEnvironmentProvider>
  )
}

Application.propTypes = {
  /* The current local "en" to loead messages from.
   * SSR and Client have different ways to read it.
   * */
  locale     :PropTypes.string.isRequired,
  /* Additional locale props, returned from the useLocale hook (needed ?). */
  localeProps:PropTypes.any.isRequired,

  /* The messages for the current locale. */
  messages:PropTypes.objectOf(PropTypes.string).isRequired,

  /* The relay environment to use. */
  relayEnvironment:PropTypes.any.isRequired,

  /* The Helmet context for SSR. */
  ssrHelmetContext:PropTypes.objectOf(PropTypes.any),

  /* The SSR hostname */
  ssrHostname:PropTypes.string,

  /* The SSR location */
  ssrLocation:PropTypes.string,

  /* The SSR router context */
  ssrRouterContext:PropTypes.objectOf(PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
  ])),

  /* The routes to use. */
  routes:PropTypes.arrayOf(PropTypes.object).isRequired,

  /* The routes to prefetch. */
  prefetchRoutes:PropTypes.arrayOf(PropTypes.object),

  /* The maintenance mode. */
  maintenance:PropTypes.any,

  /* The application query. */
  QUERY_APPLICATION:PropTypes.any.isRequired,

  /* The application query variables. */
  applicationQueryVariables:PropTypes.objectOf(PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
  ])),

  /* The default redirection after login. */
  defaultRedirectionAfterLogin:PropTypes.string,

  /* The logout mutation. */
  MUTATION_LOGOUT:PropTypes.any.isRequired,

  /* The 404 page component to render in case no routes match. */
  Status404Page:PropTypes.elementType.isRequired,

  /* The fragment for the viewer. */
  FRAGMENT_VIEWER:PropTypes.any.isRequired,

  /* The login path. */
  loginPath:PropTypes.string,
}

export default Application
