// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { memoizeFnAll, toFlatCommunicationIdentifier } from "../../../acs-ui-common/src";
import memoizeOne from 'memoize-one';
import { _convertParticipantState } from './callUtils';
import { maskDisplayNameWithRole } from './callUtils';
import { checkIsSpeaking } from './SelectorUtils';
import { isPhoneNumberIdentifier } from '@azure/communication-common';
import { memoizedConvertToVideoTileReaction } from './participantListSelectorUtils';
/** @internal */
export const _dominantSpeakersWithFlatId = (dominantSpeakers) => {
    var _a;
    return (_a = dominantSpeakers === null || dominantSpeakers === void 0 ? void 0 : dominantSpeakers.speakersList) === null || _a === void 0 ? void 0 : _a.map(toFlatCommunicationIdentifier);
};
/** @internal */
export const _videoGalleryRemoteParticipantsMemo = (remoteParticipants, isHideAttendeeNamesEnabled, localUserRole) => {
    if (!remoteParticipants) {
        return [];
    }
    return memoizedAllConvertRemoteParticipant(memoizedFn => {
        return Object.values(remoteParticipants)
            /**
             * hiding participants who are inLobby, idle, or connecting in ACS clients till we can admit users through ACS clients.
             * phone users will be in the connecting state until they are connected to the call.
             */ .filter((participant) => {
            return !['InLobby', 'Idle', 'Connecting', 'Disconnected'].includes(participant.state) || isPhoneNumberIdentifier(participant.identifier);
        }).map((participant) => {
            const state = _convertParticipantState(participant);
            const displayName = maskDisplayNameWithRole(participant.displayName, localUserRole, participant.role, isHideAttendeeNamesEnabled);
            const remoteParticipantReaction = memoizedConvertToVideoTileReaction(participant.reactionState);
            const spotlight = participant.spotlight;
            return memoizedFn(toFlatCommunicationIdentifier(participant.identifier), participant.isMuted, checkIsSpeaking(participant), participant.videoStreams, state, displayName, participant.raisedHand, participant.contentSharingStream, remoteParticipantReaction, spotlight, participant.mediaAccess, participant.role);
        });
    });
};
const memoizedAllConvertRemoteParticipant = memoizeFnAll((userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, mediaAccess, role, signalStrength) => {
    return convertRemoteParticipantToVideoGalleryRemoteParticipant(userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, signalStrength, mediaAccess, role);
});
/** @private */
export const convertRemoteParticipantToVideoGalleryRemoteParticipant = (userId, isMuted, isSpeaking, videoStreams, state, displayName, raisedHand, contentSharingStream, reaction, spotlight, signalStrength, mediaAccess, role) => {
    const rawVideoStreamsArray = Object.values(videoStreams);
    let videoStream = undefined;
    let screenShareStream = undefined;
    /**
     * There is a bug from the calling sdk where if a user leaves and rejoins immediately
     * it adds 2 more potential streams this remote participant can use. The old 2 streams
     * still show as available and that is how we got a frozen stream in this case. The stopgap
     * until streams accurately reflect their availability is to always prioritize the latest streams of a certain type
     * e.g findLast instead of find
     */
    const sdkRemoteVideoStream = Object.values(rawVideoStreamsArray).findLast(i => i.mediaStreamType === 'Video' && i.isAvailable) || Object.values(rawVideoStreamsArray).findLast(i => i.mediaStreamType === 'Video');
    const sdkScreenShareStream = Object.values(rawVideoStreamsArray).findLast(i => i.mediaStreamType === 'ScreenSharing' && i.isAvailable) || Object.values(rawVideoStreamsArray).findLast(i => i.mediaStreamType === 'ScreenSharing');
    if (sdkRemoteVideoStream) {
        videoStream = convertRemoteVideoStreamToVideoGalleryStream(sdkRemoteVideoStream);
    }
    if (sdkScreenShareStream) {
        screenShareStream = convertRemoteVideoStreamToVideoGalleryStream(sdkScreenShareStream);
    }
    if (contentSharingStream) {
        screenShareStream = convertRemoteContentSharingStreamToVideoGalleryStream(contentSharingStream);
    }
    return {
        userId,
        displayName,
        isMuted,
        isSpeaking,
        videoStream,
        screenShareStream,
        isScreenSharingOn: screenShareStream !== undefined && screenShareStream.isAvailable,
        state,
        raisedHand,
        reaction,
        spotlight,
        mediaAccess,
        canAudioBeForbidden: role === 'Attendee',
        canVideoBeForbidden: role === 'Attendee'
    };
};
const convertRemoteVideoStreamToVideoGalleryStream = (stream) => {
    var _a, _b, _c;
    return {
        id: stream.id,
        isAvailable: stream.isAvailable,
        isReceiving: stream.isReceiving,
        isMirrored: (_a = stream.view) === null || _a === void 0 ? void 0 : _a.isMirrored,
        renderElement: (_b = stream.view) === null || _b === void 0 ? void 0 : _b.target,
        scalingMode: (_c = stream.view) === null || _c === void 0 ? void 0 : _c.scalingMode,
        streamSize: stream.streamSize
    };
};
const convertRemoteContentSharingStreamToVideoGalleryStream = (stream) => {
    return {
        isAvailable: !!stream,
        isReceiving: true,
        isMirrored: false,
        renderElement: stream
    };
};
/** @private */
export const memoizeLocalParticipant = memoizeOne((identifier, displayName, isMuted, isScreenSharingOn, localVideoStream, localScreenSharingStream, role, raisedHand, reaction, localSpotlight, capabilities) => {
    var _a, _b, _c;
    return ({
        userId: identifier,
        displayName: displayName !== null && displayName !== void 0 ? displayName : '',
        isMuted: isMuted,
        isScreenSharingOn: isScreenSharingOn,
        videoStream: {
            isAvailable: !!localVideoStream,
            isMirrored: (_a = localVideoStream === null || localVideoStream === void 0 ? void 0 : localVideoStream.view) === null || _a === void 0 ? void 0 : _a.isMirrored,
            renderElement: (_b = localVideoStream === null || localVideoStream === void 0 ? void 0 : localVideoStream.view) === null || _b === void 0 ? void 0 : _b.target
        },
        screenShareStream: {
            isAvailable: !!localScreenSharingStream,
            renderElement: (_c = localScreenSharingStream === null || localScreenSharingStream === void 0 ? void 0 : localScreenSharingStream.view) === null || _c === void 0 ? void 0 : _c.target
        },
        role,
        raisedHand: raisedHand,
        reaction,
        spotlight: localSpotlight,
        capabilities,
        mediaAccess: {
            isAudioPermitted: (capabilities === null || capabilities === void 0 ? void 0 : capabilities.unmuteMic) ? capabilities.unmuteMic.isPresent : true,
            isVideoPermitted: (capabilities === null || capabilities === void 0 ? void 0 : capabilities.turnVideoOn) ? capabilities.turnVideoOn.isPresent : true
        }
    });
});
/** @private */
export const memoizeSpotlightedParticipantIds = memoizeOne(spotlightedParticipants => spotlightedParticipants === null || spotlightedParticipants === void 0 ? void 0 : spotlightedParticipants.map((p) => toFlatCommunicationIdentifier(p.identifier)));
/** @private */
export const memoizeTogetherModeStreams = memoizeOne(togetherModeStreams => {
    var _a, _b, _c, _d, _e, _f;
    return ({
        mainVideoStream: {
            id: (_a = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _a === void 0 ? void 0 : _a.id,
            isReceiving: (_b = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _b === void 0 ? void 0 : _b.isReceiving,
            isAvailable: (_c = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _c === void 0 ? void 0 : _c.isAvailable,
            renderElement: (_e = (_d = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _d === void 0 ? void 0 : _d.view) === null || _e === void 0 ? void 0 : _e.target,
            streamSize: (_f = togetherModeStreams === null || togetherModeStreams === void 0 ? void 0 : togetherModeStreams.mainVideoStream) === null || _f === void 0 ? void 0 : _f.streamSize
        }
    });
});
/** @private */
export const memoizeTogetherModeSeatingPositions = memoizeOne(togetherModeSeatingCoordinates => togetherModeSeatingCoordinates);
//# sourceMappingURL=videoGalleryUtils.js.map