// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Customizer, LayerHost, mergeStyles, registerIcons, Stack, useTheme } from '@fluentui/react';
import { FluentThemeProvider } from "../../../../react-components/src";
import React, { createContext, useContext } from 'react';
import { LocalizationProvider } from '../localization';
import { DEFAULT_COMPOSITE_ICONS } from './icons';
import { globalLayerHostStyle } from './styles/GlobalHostLayer.styles';
import { useId } from '@fluentui/react-hooks';
import { ACSAudioProvider } from './AudioProvider';
/**
 * A base provider {@link React.Context} to wrap components with other required providers
 * (e.g. icons, FluentThemeProvider, LocalizationProvider).
 *
 * Required providers are only wrapped once, with all other instances only passing children.
 *
 * @private
 */
export const BaseProvider = (props) => {
    const { fluentTheme, rtl, locale } = props;
    const globalLayerHostId = useId('composite-global-hostId');
    /**
     * Pass only the children if we previously registered icons, and have previously wrapped the children in
     * FluentThemeProvider and LocalizationProvider
     */
    const alreadyWrapped = useBase();
    if (alreadyWrapped) {
        return React.createElement(React.Fragment, null, props.children);
    }
    /**
     * Before registering fluent icons, we should check DEFAULT_COMPOSITE_ICONS and strip out the key value pairs where value is undefined
     */
    const iconsToRegister = {};
    Object.entries(DEFAULT_COMPOSITE_ICONS).forEach(([key, value]) => {
        if (value) {
            iconsToRegister[key] = value;
        }
    });
    /**
     * We register the default icon mappings merged with custom icons provided through props
     * to ensure all icons render correctly.
     */
    registerIcons({
        icons: Object.assign(Object.assign({}, iconsToRegister), props.icons)
    });
    /**
     * We need to create one context for the AudioProvider to ensure that we only have one instance of the AudioContext.
     */
    const compositeAudioContext = new AudioContext();
    // we use Customizer to override default LayerHost injected to <body />
    // which stop polluting global dom tree and increase compatibility with react-full-screen
    const CompositeElement = React.createElement(FluentThemeProvider, { fluentTheme: fluentTheme, rtl: rtl },
        // On mobile we expect the composite to fill the device screen, hence we set a meta property to have better OOBE.
        props.formFactor === 'mobile' && React.createElement("meta", { name: "viewport", content: "width=device-width" }),
        React.createElement(Customizer, { scopedSettings: {
                Layer: {
                    hostId: globalLayerHostId
                }
            } },
            React.createElement(ACSAudioProvider, { audioContext: compositeAudioContext },
                React.createElement(WithBackgroundColor, null, props.children))),
        React.createElement(LayerHost, { id: globalLayerHostId, className: mergeStyles(globalLayerHostStyle) }));
    const localizedElement = locale ? LocalizationProvider({
        locale,
        children: CompositeElement
    }) : CompositeElement;
    return React.createElement(BaseContext.Provider, { value: true }, localizedElement);
};
/**
 * @private
 */
const BaseContext = createContext(false);
/**
 * @private
 */
const useBase = () => useContext(BaseContext);
/**
 * @private
 * Provides a wrapper with a background color to ensure that composites always have a background color.
 * This is necessary to ensure that composites are not transparent,
 * and the background color of it's parent elements doesn't show through the composite.
 */
const WithBackgroundColor = (props) => {
    const { children } = props;
    const theme = useTheme();
    const className = mergeStyles({
        background: theme.semanticColors.bodyBackground,
        height: '100%',
        width: '100%',
        position: 'relative'
    });
    return React.createElement(Stack, { className: className }, children);
};
//# sourceMappingURL=BaseComposite.js.map