import React, { PropsWithChildren, useEffect } from 'react';
import { BrowserRouter } from 'react-router-dom';
import { IntlProvider } from 'react-intl';
import { ApolloProvider } from '@apollo/client';
import { CssBaseline, ThemeProvider } from '@material-ui/core';
import { Config, useConfig } from '@elephant-healthcare/config-provider';
import { Auth0ProviderWithHistory } from '@elephant-healthcare/auth0-provider';

import { generateTheme } from './style/theme';
import { getApolloClient } from './apollo';
import getBasename from './getBasename';
import { ErrorEvent, Event, FontConfig } from './types';

interface Props {
  appVersion: string;
  emitAnalyticsEvent: (event: Event) => void;
  emitErrorEvent: (event: ErrorEvent) => void;
  onConfigChange?: (config: Config) => void;
  fontConfig: FontConfig;
}

const Providers = ({
  appVersion,
  emitAnalyticsEvent,
  emitErrorEvent,
  onConfigChange,
  fontConfig,
  children,
}: PropsWithChildren<Props>) => {
  const config = useConfig();

  useEffect(() => {
    onConfigChange?.(config);
  }, [config]);

  const theme = generateTheme(fontConfig);

  return (
    <IntlProvider locale="en">
      <ApolloProvider
        client={getApolloClient({
          federationPath: config.federationPath,
          territory: config.territory,
          appVersion,
          emitAnalyticsEvent,
          emitErrorEvent,
        })}
      >
        <ThemeProvider theme={theme}>
          <CssBaseline />
          <BrowserRouter basename={getBasename()}>
            <Auth0ProviderWithHistory
              domain={config.auth0.domain}
              clientId={config.auth0.clientId}
              internalProxyDomain={config.auth0.internalProxyDomain}
              emitErrorEvent={emitErrorEvent}
            >
              {children}
            </Auth0ProviderWithHistory>
          </BrowserRouter>
        </ThemeProvider>
      </ApolloProvider>
    </IntlProvider>
  );
};

export { Providers };
