// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { memoizeFunction, Stack, useTheme } from '@fluentui/react';
import { ControlBar, DevicesButton } from "../../../../../react-components/src";
import { HoldButton } from "../../../../../react-components/src";
import React, { useMemo, useCallback, useState, useEffect } from 'react';
import { Camera } from './buttons/Camera';
import { Devices } from './buttons/Devices';
import { EndCall } from './buttons/EndCall';
import { Microphone } from './buttons/Microphone';
import { Participants } from './buttons/Participants';
import { ScreenShare } from './buttons/ScreenShare';
import { People } from './buttons/People';
import { useLocale } from '../../localization';
import { MoreButton } from '../../common/MoreButton';
import { usePropsFor } from '../hooks/usePropsFor';
import { buttonFlyoutIncreasedSizeStyles } from '../styles/Buttons.styles';
import { useAdapter } from '../adapter/CallAdapterProvider';
import { isDisabled } from '../utils';
import { callControlsContainerStyles } from '../styles/CallPage.styles';
import { RaiseHand } from './buttons/RaiseHand';
import { RaiseHandButton } from "../../../../../react-components/src";
import { _generateDefaultDeviceMenuProps } from "../../../../../react-components/src";
import { CUSTOM_BUTTON_OPTIONS, generateCustomCallControlBarButton, generateCustomCallDesktopOverflowButtons, onFetchCustomButtonPropsTrampoline } from '../../common/ControlBar/CustomButton';
import { Reaction } from './buttons/Reaction';
import { useSelector } from '../hooks/useSelector';
import { capabilitySelector } from '../../CallComposite/selectors/capabilitySelector';
import { callStatusSelector } from '../../CallComposite/selectors/callStatusSelector';
import { _isSafari } from '../../CallComposite/utils';
import { getIsRoomsCall, getReactionResources, getRole, getDeepNoiseSuppresionEffectsDependency, getDeepNoiseSuppresionIsOnByDefault, getHideDeepNoiseSupressionButton, getEnvironmentInfo } from '../selectors/baseSelectors';
// Enforce a background color on control bar to ensure it matches the composite background color.
const controlBarStyles = memoizeFunction((background) => ({
    root: {
        background: background
    }
}));
const inferCallControlOptions = (mobileView, callControlOptions) => {
    if (callControlOptions === false) {
        return {};
    }
    const options = callControlOptions === true || callControlOptions === undefined ? {} : callControlOptions;
    if (mobileView) {
        // Set options to always not show screen share button for mobile
        options.screenShareButton = false;
    }
    return options;
};
/**
 * @private
 */
export const CallControls = (props) => {
    var _a;
    const options = useMemo(() => inferCallControlOptions(!!props.isMobile, props.options), [props.isMobile, props.options]);
    const localeStrings = useLocale();
    const [isDeepNoiseSuppressionOn, setDeepNoiseSuppressionOn] = useState(false);
    const adapter = useAdapter();
    const startDeepNoiseSuppression = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        yield adapter.startNoiseSuppressionEffect();
    }), [adapter]);
    const deepNoiseSuppresionEffectsDependency = useSelector(getDeepNoiseSuppresionEffectsDependency);
    const deepNoiseSuppressionOnByDefault = useSelector(getDeepNoiseSuppresionIsOnByDefault);
    useEffect(() => {
        if (deepNoiseSuppresionEffectsDependency && deepNoiseSuppressionOnByDefault) {
            startDeepNoiseSuppression();
            setDeepNoiseSuppressionOn(true);
        }
    }, [deepNoiseSuppresionEffectsDependency, deepNoiseSuppressionOnByDefault, startDeepNoiseSuppression]);
    const environmentInfo = useSelector(getEnvironmentInfo);
    const isSafari = _isSafari(environmentInfo);
    const hideDeepNoiseSuppressionButton = useSelector(getHideDeepNoiseSupressionButton);
    const showNoiseSuppressionButton = !!(deepNoiseSuppresionEffectsDependency && !hideDeepNoiseSuppressionButton && !isSafari);
    const onClickNoiseSuppression = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
        if (isDeepNoiseSuppressionOn) {
            yield adapter.stopNoiseSuppressionEffect();
            setDeepNoiseSuppressionOn(false);
        }
        else {
            yield adapter.startNoiseSuppressionEffect();
            setDeepNoiseSuppressionOn(true);
        }
    }), [adapter, isDeepNoiseSuppressionOn]);
    const peopleButtonStrings = useMemo(() => ({
        label: localeStrings.strings.call.peopleButtonLabel,
        tooltipOffContent: localeStrings.strings.call.peopleButtonTooltipOpen,
        tooltipOnContent: localeStrings.strings.call.peopleButtonTooltipClose
    }), [localeStrings]);
    const moreButtonStrings = useMemo(() => ({
        label: localeStrings.strings.call.moreButtonCallingLabel,
        tooltipOffContent: localeStrings.strings.callWithChat.moreDrawerButtonTooltip
    }), [localeStrings]);
    const holdButtonProps = usePropsFor(HoldButton);
    const raiseHandButtonProps = usePropsFor(RaiseHandButton);
    const capabilitiesSelector = useSelector(capabilitySelector);
    const callState = useSelector(callStatusSelector);
    const isReactionAllowed = callState.callStatus !== 'Connected' || !(capabilitiesSelector === null || capabilitiesSelector === void 0 ? void 0 : capabilitiesSelector.capabilities) || capabilitiesSelector.capabilities.useReactions.isPresent;
    const devicesButtonProps = usePropsFor(DevicesButton);
    let numberOfButtons = 0;
    const screenShareButtonIsEnabled = isEnabled(options === null || options === void 0 ? void 0 : options.screenShareButton);
    if (screenShareButtonIsEnabled) {
        numberOfButtons++;
    }
    const microphoneButtonIsEnabled = isEnabled(options === null || options === void 0 ? void 0 : options.microphoneButton);
    if (microphoneButtonIsEnabled) {
        numberOfButtons++;
    }
    const cameraButtonIsEnabled = isEnabled(options === null || options === void 0 ? void 0 : options.cameraButton);
    if (cameraButtonIsEnabled) {
        numberOfButtons++;
    }
    if (isEnabled(options === null || options === void 0 ? void 0 : options.endCallButton)) {
        numberOfButtons++;
    }
    const showParticipantsButtonInControlBar = isEnabled(options === null || options === void 0 ? void 0 : options.participantsButton) && !props.isMobile;
    if (showParticipantsButtonInControlBar) {
        numberOfButtons++;
    }
    const showReactionButtonInControlBar = isEnabled(options === null || options === void 0 ? void 0 : options.reactionButton) && isReactionAllowed && !props.isMobile;
    if (showReactionButtonInControlBar) {
        numberOfButtons++;
    }
    const isRoomsCall = useSelector(getIsRoomsCall);
    const moreButtonContextualMenuItems = () => {
        const items = [];
        if (props.isMobile && props.onPeopleButtonClicked && isEnabled(options === null || options === void 0 ? void 0 : options.participantsButton)) {
            items.push({
                key: 'peopleButtonKey',
                text: localeStrings.component.strings.participantsButton.label,
                onClick: () => {
                    if (props.onPeopleButtonClicked) {
                        props.onPeopleButtonClicked();
                    }
                },
                iconProps: {
                    iconName: 'ControlButtonParticipantsContextualMenuItem',
                    styles: {
                        root: {
                            lineHeight: 0
                        }
                    }
                },
                itemProps: {
                    styles: buttonFlyoutIncreasedSizeStyles
                },
                disabled: isDisabled(options === null || options === void 0 ? void 0 : options.participantsButton),
                ['data-ui-id']: 'call-composite-more-menu-people-button'
            });
        }
        if (!isRoomsCall) {
            items.push({
                key: 'holdButtonKey',
                text: localeStrings.component.strings.holdButton.tooltipOffContent,
                onClick: () => {
                    holdButtonProps.onToggleHold();
                },
                iconProps: {
                    iconName: 'HoldCallContextualMenuItem',
                    styles: {
                        root: {
                            lineHeight: 0
                        }
                    }
                },
                itemProps: {
                    styles: buttonFlyoutIncreasedSizeStyles
                },
                disabled: isDisabled(options === null || options === void 0 ? void 0 : options.holdButton),
                ['data-ui-id']: 'hold-button'
            });
        }
        return items;
    };
    const customDrawerButtons = useMemo(() => generateCustomCallDesktopOverflowButtons(onFetchCustomButtonPropsTrampoline(typeof options === 'object' ? options : undefined), typeof options === 'object' ? options.displayType : undefined), [options]);
    const moreButtonMenuItems = moreButtonContextualMenuItems();
    let showMoreButton = isEnabled(options === null || options === void 0 ? void 0 : options.moreButton) && moreButtonMenuItems.length > 0;
    if (showMoreButton) {
        numberOfButtons++;
    }
    const customButtons = useMemo(() => generateCustomCallControlBarButton(onFetchCustomButtonPropsTrampoline(options), options === null || options === void 0 ? void 0 : options.displayType), [options]);
    numberOfButtons += React.Children.count(customButtons['primary']) + React.Children.count(customButtons['secondary']);
    let showDevicesButtonInControlBar = isEnabled(options === null || options === void 0 ? void 0 : options.devicesButton);
    if (showDevicesButtonInControlBar && (props.isMobile ? numberOfButtons < 5 : true)) {
        numberOfButtons++;
    }
    else {
        showDevicesButtonInControlBar = false;
        showMoreButton = isEnabled(options === null || options === void 0 ? void 0 : options.moreButton);
    }
    const reactionResources = useSelector(getReactionResources);
    const raiseHandButtonIsEnabled = isEnabled(options === null || options === void 0 ? void 0 : options.raiseHandButton);
    let showRaiseHandButtonInControlBar = raiseHandButtonIsEnabled;
    const role = useSelector(getRole);
    const hideRaiseHandButtonInRoomsCall = isRoomsCall && role && ['Consumer', 'Unknown'].includes(role);
    if (showRaiseHandButtonInControlBar && (props.isMobile ? numberOfButtons < 5 : true)) {
        numberOfButtons++;
    }
    else {
        // If more button is not present but enabled then replace previous button (devices button) with more button
        if (!showMoreButton && isEnabled(options === null || options === void 0 ? void 0 : options.moreButton)) {
            showMoreButton = true;
            showDevicesButtonInControlBar = false;
        }
        showRaiseHandButtonInControlBar = false;
    }
    if (!showDevicesButtonInControlBar) {
        const devicesButtonMenu = _generateDefaultDeviceMenuProps(devicesButtonProps, localeStrings.component.strings.devicesButton);
        moreButtonMenuItems.push({
            key: 'devicesButtonKey',
            text: localeStrings.component.strings.devicesButton.label,
            iconProps: {
                iconName: 'ControlButtonOptions',
                styles: {
                    root: {
                        lineHeight: 0
                    }
                }
            },
            subMenuProps: devicesButtonMenu,
            ['data-ui-id']: 'call-composite-more-menu-devices-button'
        });
    }
    if (!showRaiseHandButtonInControlBar && !hideRaiseHandButtonInRoomsCall) {
        moreButtonMenuItems.push({
            key: 'raiseHandButtonKey',
            text: raiseHandButtonProps.checked ? localeStrings.component.strings.raiseHandButton.onLabel : localeStrings.component.strings.raiseHandButton.offLabel,
            onClick: () => {
                if (raiseHandButtonProps.onToggleRaiseHand) {
                    raiseHandButtonProps.onToggleRaiseHand();
                }
            },
            iconProps: {
                iconName: 'RaiseHandContextualMenuItem',
                styles: {
                    root: {
                        lineHeight: 0
                    }
                }
            },
            itemProps: {
                styles: buttonFlyoutIncreasedSizeStyles
            },
            disabled: isDisabled(options === null || options === void 0 ? void 0 : options.raiseHandButton),
            ['data-ui-id']: 'call-composite-more-menu-raise-hand-button'
        });
    }
    // Custom Buttons in More Button Menu should always be the last items pushed into the moreButtonMenuItems array
    if (customDrawerButtons['primary']) {
        customDrawerButtons['primary'].slice(props.isMobile ? CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_MOBILE_CUSTOM_BUTTONS : CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_DESKTOP_CUSTOM_BUTTONS).forEach(element => {
            moreButtonMenuItems.push(Object.assign({ itemProps: {
                    styles: buttonFlyoutIncreasedSizeStyles
                } }, element));
        });
    }
    if (customDrawerButtons['secondary']) {
        customDrawerButtons['secondary'].forEach(element => {
            moreButtonMenuItems.push(Object.assign({ itemProps: {
                    styles: buttonFlyoutIncreasedSizeStyles
                } }, element));
        });
    }
    if (customDrawerButtons['overflow']) {
        customDrawerButtons['overflow'].forEach(element => {
            moreButtonMenuItems.push(Object.assign({ itemProps: {
                    styles: buttonFlyoutIncreasedSizeStyles
                } }, element));
        });
    }
    const theme = useTheme();
    // when props.options is false then we want to hide the whole control bar.
    if (props.options === false) {
        return React.createElement(React.Fragment, null);
    }
    return React.createElement(Stack, { horizontalAlign: "center", className: callControlsContainerStyles },
        React.createElement(Stack.Item, null,
            React.createElement(ControlBar, { layout: props.displayVertical ? 'vertical' : 'horizontal', styles: controlBarStyles(theme.semanticColors.bodyBackground) },
                microphoneButtonIsEnabled && React.createElement(Microphone, { displayType: options === null || options === void 0 ? void 0 : options.displayType, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.microphoneButton), onClickNoiseSuppression: onClickNoiseSuppression, isDeepNoiseSuppressionOn: isDeepNoiseSuppressionOn, showNoiseSuppressionButton: showNoiseSuppressionButton }),
                cameraButtonIsEnabled && React.createElement(Camera, { displayType: options === null || options === void 0 ? void 0 : options.displayType, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.cameraButton) }),
                showReactionButtonInControlBar && reactionResources && React.createElement(Reaction, { displayType: options === null || options === void 0 ? void 0 : options.displayType, reactionResource: reactionResources }),
                showRaiseHandButtonInControlBar && !hideRaiseHandButtonInRoomsCall && React.createElement(RaiseHand, { displayType: options === null || options === void 0 ? void 0 : options.displayType }),
                screenShareButtonIsEnabled && React.createElement(ScreenShare, { option: options === null || options === void 0 ? void 0 : options.screenShareButton, displayType: options === null || options === void 0 ? void 0 : options.displayType, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.screenShareButton) }),
                showParticipantsButtonInControlBar && React.createElement(Participants, { option: options === null || options === void 0 ? void 0 : options.participantsButton, callInvitationURL: props.callInvitationURL, onFetchParticipantMenuItems: props.onFetchParticipantMenuItems, displayType: options === null || options === void 0 ? void 0 : options.displayType, increaseFlyoutItemSize: props.increaseFlyoutItemSize, isMobile: props.isMobile, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.participantsButton) }) && React.createElement(People, { checked: props.peopleButtonChecked, ariaLabel: peopleButtonStrings === null || peopleButtonStrings === void 0 ? void 0 : peopleButtonStrings.label, showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact', onClick: props.onPeopleButtonClicked, "data-ui-id": "call-composite-people-button", strings: peopleButtonStrings, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.participantsButton), disableTooltip: props.isMobile }),
                showDevicesButtonInControlBar && React.createElement(Devices, { displayType: options === null || options === void 0 ? void 0 : options.displayType, increaseFlyoutItemSize: props.increaseFlyoutItemSize, disabled: isDisabled(options === null || options === void 0 ? void 0 : options.devicesButton) }), (_a = customButtons['primary']) === null || _a === void 0 ? void 0 :
                _a.slice(0, props.isMobile ? CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_MOBILE_CUSTOM_BUTTONS : CUSTOM_BUTTON_OPTIONS.MAX_PRIMARY_DESKTOP_CUSTOM_BUTTONS).map((CustomButton, i) => {
                    return React.createElement(CustomButton, { key: `primary-custom-button-${i}`, 
                        // styles={commonButtonStyles}
                        showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact', disableTooltip: props.isMobile });
                }),
                showMoreButton && React.createElement(MoreButton, { disableTooltip: props.isMobile, "data-ui-id": "common-call-composite-more-button", strings: moreButtonStrings, menuIconProps: {
                        hidden: true
                    }, menuProps: {
                        items: moreButtonMenuItems
                    }, showLabel: (options === null || options === void 0 ? void 0 : options.displayType) !== 'compact' }),
                isEnabled(options === null || options === void 0 ? void 0 : options.endCallButton) && React.createElement(EndCall, { displayType: options === null || options === void 0 ? void 0 : options.displayType }))));
};
const isEnabled = (option) => option !== false;
//# sourceMappingURL=CallControls.js.map