import { CacheProvider, ThemeProvider } from '@emotion/react';
import { MotionConfig } from 'framer-motion';
import { setNonce } from 'get-nonce';
import { useContext, useEffect, useMemo, useRef } from 'react';
import * as React from 'react';
import { createEmotionCache } from './cache';
import { Reboot, Typography } from './globals';
import { Variables } from './globals/Variables';
import { coreTheme } from './themes/core';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
export const GamutContext = /*#__PURE__*/React.createContext({
  hasGlobals: false,
  hasCache: false
});
GamutContext.displayName = 'GamutContext';

/**
 * Returns the CSP nonce passed to GamutProvider, if any.
 */
export const useNonce = () => useContext(GamutContext).nonce;
export const GamutProvider = ({
  children,
  cache,
  theme = coreTheme,
  variables,
  useGlobals = true,
  useCache = true,
  nonce,
  useLogicalProperties = false
}) => {
  const {
    hasGlobals,
    hasCache
  } = useContext(GamutContext);
  const shouldCreateCache = useCache && !hasCache;
  const shouldInsertGlobals = useGlobals && !hasGlobals;

  // Feed nonce to get-nonce singleton so react-style-singleton (e.g. via react-aria-components) can set it on injected style tags for CSP
  useEffect(() => {
    if (nonce) {
      setNonce(nonce);
    }
  }, [nonce]);

  // Do not initialize a new cache if one has been provided as props
  const activeCache = useRef(shouldCreateCache && (cache ?? createEmotionCache(nonce ? {
    nonce
  } : {})));
  const contextValue = {
    hasGlobals: shouldInsertGlobals,
    hasCache: shouldCreateCache,
    useLogicalProperties,
    nonce
  };

  // Merge useLogicalProperties into theme so variance can access it via props.theme.
  const themeWithLogicalProperties = useMemo(() => ({
    ...theme,
    useLogicalProperties
  }), [theme, useLogicalProperties]);
  const globals = shouldInsertGlobals && /*#__PURE__*/_jsxs(_Fragment, {
    children: [/*#__PURE__*/_jsx(Typography, {
      theme: themeWithLogicalProperties
    }), /*#__PURE__*/_jsx(Reboot, {
      theme: themeWithLogicalProperties
    }), /*#__PURE__*/_jsx(Variables, {
      variables: theme._variables
    }), variables && /*#__PURE__*/_jsx(Variables, {
      variables: variables
    })]
  });
  const content = useMemo(() => /*#__PURE__*/_jsx(ThemeProvider, {
    theme: themeWithLogicalProperties,
    children: nonce ? /*#__PURE__*/_jsx(MotionConfig, {
      nonce: nonce,
      children: children
    }) : children
  }), [themeWithLogicalProperties, nonce, children]);
  if (activeCache.current) {
    return /*#__PURE__*/_jsx(GamutContext.Provider, {
      value: contextValue,
      children: /*#__PURE__*/_jsxs(CacheProvider, {
        value: activeCache.current,
        children: [globals, content]
      })
    });
  }
  return /*#__PURE__*/_jsxs(GamutContext.Provider, {
    value: contextValue,
    children: [globals, content]
  });
};