// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { mergeStyles, Stack, Spinner } from '@fluentui/react';
import { concatStyleSets, Layer } from '@fluentui/react';
import { _formatString } from "../../../acs-ui-common/src";
import React, { useMemo } from 'react';
import { useCallback } from 'react';
import { LocalVideoCameraCycleButton } from './LocalVideoCameraButton';
import { StreamMedia } from './StreamMedia';
import { useLocalVideoStreamLifecycleMaintainer } from './VideoGallery/useVideoStreamLifecycleMaintainer';
import { VideoTile } from './VideoTile';
import { useTheme } from '../theming';
import { MeetingReactionOverlay } from './MeetingReactionOverlay';
import { useVideoTileContextualMenuProps } from './VideoGallery/useVideoTileContextualMenuProps';
import { _DrawerMenu } from './Drawer';
import { drawerMenuWrapperStyles } from './VideoGallery/styles/RemoteVideoTile.styles';
import { videoContainerStyles, overlayStyles, overlayStylesTransparent, loadSpinnerStyles } from './styles/VideoTile.styles';
/**
 * A memoized version of VideoTile for rendering local participant.
 *
 * @internal
 */
export const _LocalVideoTile = React.memo((props) => {
    const { isAvailable, isMuted, onCreateLocalStreamView, onDisposeLocalStreamView, localVideoViewOptions, renderElement, userId, showLabel, alwaysShowLabelBackground, displayName, initialsName, onRenderAvatar, showMuteIndicator, styles, showCameraSwitcherInLocalPreview, localVideoCameraCycleButtonProps, localVideoCameraSwitcherLabel, localVideoSelectedDescription, raisedHand, reaction, isSpotlighted, spotlightedParticipantUserIds, onStartSpotlight, onStopSpotlight, maxParticipantsToSpotlight, menuKind, strings, reactionResources, isScreenSharingOn, mediaAccess } = props;
    const theme = useTheme();
    const localVideoStreamProps = useMemo(() => ({
        isMirrored: localVideoViewOptions === null || localVideoViewOptions === void 0 ? void 0 : localVideoViewOptions.isMirrored,
        isStreamAvailable: isAvailable,
        onCreateLocalStreamView,
        onDisposeLocalStreamView,
        renderElementExists: !!renderElement,
        scalingMode: localVideoViewOptions === null || localVideoViewOptions === void 0 ? void 0 : localVideoViewOptions.scalingMode,
        isVideoPermitted: mediaAccess ? mediaAccess.isVideoPermitted : true
    }), [isAvailable, localVideoViewOptions === null || localVideoViewOptions === void 0 ? void 0 : localVideoViewOptions.isMirrored, localVideoViewOptions === null || localVideoViewOptions === void 0 ? void 0 : localVideoViewOptions.scalingMode, onCreateLocalStreamView, onDisposeLocalStreamView, renderElement, mediaAccess]);
    // Handle creating, destroying and updating the video stream as necessary
    useLocalVideoStreamLifecycleMaintainer(localVideoStreamProps);
    const contextualMenuProps = useVideoTileContextualMenuProps({
        participant: {
            userId: userId !== null && userId !== void 0 ? userId : ''
        },
        strings: Object.assign({}, strings),
        spotlightedParticipantUserIds,
        isSpotlighted,
        onStartSpotlight,
        onStopSpotlight,
        maxParticipantsToSpotlight,
        myUserId: userId
    });
    const videoTileContextualMenuProps = useMemo(() => {
        if (menuKind !== 'contextual' || !contextualMenuProps) {
            return {};
        }
        return {
            contextualMenu: contextualMenuProps
        };
    }, [contextualMenuProps, menuKind]);
    const videoTileStyles = useMemo(() => {
        if (isSpotlighted) {
            return concatStyleSets({
                root: {
                    outline: `0.25rem solid ${theme.palette.neutralTertiaryAlt}`,
                    outlineOffset: '-0.25rem'
                }
            }, styles);
        }
        return styles;
    }, [isSpotlighted, theme.palette.neutralTertiaryAlt, styles]);
    const [drawerMenuItemProps, setDrawerMenuItemProps] = React.useState([]);
    const onKeyDown = useCallback((e) => {
        if (e.key === 'Enter') {
            setDrawerMenuItemProps(convertContextualMenuItemsToDrawerMenuItemProps(contextualMenuProps, () => setDrawerMenuItemProps([])));
        }
    }, [setDrawerMenuItemProps, contextualMenuProps]);
    const renderVideoStreamElement = useMemo(() => {
        // Checking if renderElement is well defined or not as calling SDK has a number of video streams limitation which
        // implies that, after their threshold, all streams have no child (blank video)
        if (!renderElement || !renderElement.childElementCount) {
            // Returning `undefined` results in the placeholder with avatar being shown
            return undefined;
        }
        return React.createElement(React.Fragment, null,
            React.createElement(FloatingLocalCameraCycleButton, { showCameraSwitcherInLocalPreview: showCameraSwitcherInLocalPreview !== null && showCameraSwitcherInLocalPreview !== void 0 ? showCameraSwitcherInLocalPreview : false, localVideoCameraCycleButtonProps: localVideoCameraCycleButtonProps, localVideoCameraSwitcherLabel: localVideoCameraSwitcherLabel, localVideoSelectedDescription: localVideoSelectedDescription }),
            React.createElement(StreamMedia, { videoStreamElement: renderElement, isMirrored: true }),
            props.participantsCount === 1 && !isScreenSharingOn && React.createElement(Stack, { className: mergeStyles(videoContainerStyles, overlayStyles()) },
                React.createElement(Spinner, { label: strings === null || strings === void 0 ? void 0 : strings.waitingScreenText, ariaLive: "assertive", role: "alert", labelPosition: "bottom", styles: loadSpinnerStyles(theme, true) })));
    }, [localVideoCameraCycleButtonProps, localVideoCameraSwitcherLabel, localVideoSelectedDescription, renderElement, showCameraSwitcherInLocalPreview, props.participantsCount, strings === null || strings === void 0 ? void 0 : strings.waitingScreenText, theme, isScreenSharingOn]);
    const videoTileOverlay = useMemo(() => {
        const reactionOverlay = reactionResources !== undefined ? React.createElement(MeetingReactionOverlay, { overlayMode: "grid-tiles", reaction: reaction, reactionResources: reactionResources }) : undefined;
        return reactionOverlay;
    }, [reaction, reactionResources]);
    const onRenderAvatarOneParticipant = useCallback(() => {
        return React.createElement(Stack, { className: mergeStyles(videoContainerStyles, overlayStylesTransparent()) },
            React.createElement(Spinner, { label: strings === null || strings === void 0 ? void 0 : strings.waitingScreenText, ariaLive: "assertive", labelPosition: "bottom", role: "alert", styles: loadSpinnerStyles(theme, false) }));
    }, [strings === null || strings === void 0 ? void 0 : strings.waitingScreenText, theme]);
    return React.createElement(Stack, { "data-ui-id": "local-video-tile", className: mergeStyles({
            width: '100%',
            height: '100%'
        }), onKeyDown: menuKind === 'drawer' ? onKeyDown : undefined },
        React.createElement(VideoTile, Object.assign({ key: userId !== null && userId !== void 0 ? userId : 'local-video-tile', userId: userId, renderElement: renderVideoStreamElement, showLabel: showLabel, alwaysShowLabelBackground: alwaysShowLabelBackground, displayName: displayName, initialsName: initialsName, styles: videoTileStyles, onRenderPlaceholder: props.participantsCount === 1 && !isScreenSharingOn ? onRenderAvatarOneParticipant : onRenderAvatar, isMuted: isMuted, showMuteIndicator: showMuteIndicator, personaMinSize: props.personaMinSize, raisedHand: raisedHand, isSpotlighted: isSpotlighted }, videoTileContextualMenuProps, { onLongTouch: () => setDrawerMenuItemProps(convertContextualMenuItemsToDrawerMenuItemProps(contextualMenuProps, () => setDrawerMenuItemProps([]))), overlay: videoTileOverlay, mediaAccess: mediaAccess }), drawerMenuItemProps.length > 0 && React.createElement(Layer, { hostId: props.drawerMenuHostId },
            React.createElement(Stack, { styles: drawerMenuWrapperStyles },
                React.createElement(_DrawerMenu, { onLightDismiss: () => setDrawerMenuItemProps([]), items: drawerMenuItemProps })))));
});
const FloatingLocalCameraCycleButton = (props) => {
    const { showCameraSwitcherInLocalPreview, localVideoCameraCycleButtonProps, localVideoCameraSwitcherLabel, localVideoSelectedDescription } = props;
    const ariaDescription = (localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.selectedCamera) && localVideoSelectedDescription && _formatString(localVideoSelectedDescription, {
        cameraName: localVideoCameraCycleButtonProps.selectedCamera.name
    });
    return React.createElement(Stack, { horizontalAlign: "end" }, showCameraSwitcherInLocalPreview && (localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.cameras) !== undefined && (localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.selectedCamera) !== undefined && (localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.onSelectCamera) !== undefined && React.createElement(LocalVideoCameraCycleButton, { cameras: localVideoCameraCycleButtonProps.cameras, selectedCamera: localVideoCameraCycleButtonProps.selectedCamera, onSelectCamera: localVideoCameraCycleButtonProps.onSelectCamera, label: localVideoCameraSwitcherLabel, ariaDescription: ariaDescription }));
};
const convertContextualMenuItemsToDrawerMenuItemProps = (contextualMenuProps, onLightDismiss) => {
    if (!contextualMenuProps) {
        return [];
    }
    return contextualMenuProps.items.map(item => {
        return {
            itemKey: item.key,
            text: item.text,
            iconProps: item.iconProps,
            disabled: item.disabled,
            onItemClick: () => {
                var _a;
                (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item);
                onLightDismiss === null || onLightDismiss === void 0 ? void 0 : onLightDismiss();
            }
        };
    });
};
//# sourceMappingURL=LocalVideoTile.js.map