/*!
 * Copyright (c) 2022-present, Okta, Inc. and/or its affiliates. All rights reserved.
 * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 */

import styled from "@emotion/styled";
import { createTheme, ThemeProvider as MuiThemeProvider } from "@mui/material/styles";
import { deepmerge } from "@mui/utils";
import * as Tokens from "@okta/odyssey-design-tokens";
import { memo, useMemo } from "react";
import { OdysseyDesignTokensContext } from "./OdysseyDesignTokensContext.js";
import { OdysseyThemeProviderPropsProvider, useOdysseyThemeProviderPropsContext } from "./OdysseyThemeProviderPropsContext.js";
import { createOdysseyMuiTheme } from "./theme/theme.js";
import { ContrastModeContext, useContrastMode } from "./useContrastMode.js";
import { jsx as _jsx } from "react/jsx-runtime";
const StyledContrastContainerStyles = styled("div")({
  height: "inherit"
});
const OdysseyThemeProvider = ({
  children,
  contrastMode: contrastModeProp,
  designTokensOverride: designTokensOverrideProp,
  hasWrapperElement = true,
  shadowDomElement,
  shadowRootElement: shadowRootElementProp,
  themeOverride: themeOverrideProp
}) => {
  const odysseyThemeProviderPropsContext = useOdysseyThemeProviderPropsContext();
  const designTokensOverride = designTokensOverrideProp ?? odysseyThemeProviderPropsContext.designTokensOverride;
  const shadowRootElement = shadowRootElementProp ?? shadowDomElement ?? odysseyThemeProviderPropsContext.shadowRootElement;
  const themeOverride = themeOverrideProp ?? odysseyThemeProviderPropsContext.themeOverride;
  const {
    contrastMode,
    contrastContainerRef
  } = useContrastMode({
    contrastMode: contrastModeProp
  });
  const odysseyTokens = useMemo(() => ({
    ...Tokens,
    ...designTokensOverride
  }), [designTokensOverride]);
  const odysseyTheme = useMemo(() => createOdysseyMuiTheme({
    contrastMode,
    odysseyTokens,
    shadowRootElement
  }), [contrastMode, odysseyTokens, shadowRootElement]);
  const customOdysseyTheme = useMemo(() => createTheme(deepmerge(odysseyTheme, themeOverride || {})), [odysseyTheme, themeOverride]);
  const contrastModeProviderValue = useMemo(() => ({
    contrastMode
  }), [contrastMode]);
  const providerComponents = useMemo(() => _jsx(ContrastModeContext.Provider, {
    value: contrastModeProviderValue,
    children: _jsx(MuiThemeProvider, {
      theme: customOdysseyTheme,
      children: _jsx(OdysseyThemeProviderPropsProvider, {
        designTokensOverride: designTokensOverride,
        shadowRootElement: shadowRootElement,
        themeOverride: themeOverride,
        children: _jsx(OdysseyDesignTokensContext.Provider, {
          value: odysseyTokens,
          children: children
        })
      })
    })
  }), [children, contrastModeProviderValue, customOdysseyTheme, designTokensOverride, odysseyTokens, shadowRootElement, themeOverride]);
  return hasWrapperElement ? _jsx(StyledContrastContainerStyles, {
    ref: contrastContainerRef,
    children: providerComponents
  }) : providerComponents;
};
const MemoizedOdysseyThemeProvider = memo(OdysseyThemeProvider);
MemoizedOdysseyThemeProvider.displayName = "OdysseyThemeProvider";
export { MemoizedOdysseyThemeProvider as OdysseyThemeProvider };
//# sourceMappingURL=OdysseyThemeProvider.js.map