// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createSelector } from 'reselect';
import { getIdentifier, getDisplayName, getIsScreenSharingOn, getIsMuted, getCapabilities } from './baseSelectors';
import { getRole } from './baseSelectors';
import { isHideAttendeeNamesEnabled } from './baseSelectors';
import { _convertParticipantState, _updateUserDisplayNames } from './utils/callUtils';
import { memoizedConvertAllremoteParticipants } from './utils/participantListSelectorUtils';
import { memoizedConvertToVideoTileReaction, memoizedSpotlight } from './utils/participantListSelectorUtils';
import { getLocalParticipantRaisedHand } from './baseSelectors';
import { getLocalParticipantReactionState } from './baseSelectors';
import { getSpotlightCallFeature } from './baseSelectors';
import { toFlatCommunicationIdentifier } from "../../acs-ui-common/src";
import { getParticipantCount } from './baseSelectors';
import { isMicrosoftTeamsAppIdentifier, isPhoneNumberIdentifier } from '@azure/communication-common';
import { maskDisplayNameWithRole } from './utils/callUtils';
import { getRemoteParticipantsExcludingConsumers } from './getRemoteParticipantsExcludingConsumers';
const convertRemoteParticipantsToParticipantListParticipants = (remoteParticipants, localUserCanRemoveOthers, isHideAttendeeNamesEnabled, localUserRole, spotlightedParticipants) => {
    const conversionCallback = (memoizeFn) => {
        return remoteParticipants
            // Filter out MicrosoftBot participants
            .filter((participant) => {
            return !isMicrosoftTeamsAppIdentifier(participant.identifier);
        })
            /**
             * 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 isScreenSharing = Object.values(participant.videoStreams).some(videoStream => videoStream.mediaStreamType === 'ScreenSharing' && videoStream.isAvailable);
            /**
             * We want to check the participant to see if they are a PSTN participant joining the call
             * and mapping their state to be 'Ringing'
             */
            const state = _convertParticipantState(participant);
            const displayName = maskDisplayNameWithRole(participant.displayName, localUserRole, participant.role, isHideAttendeeNamesEnabled);
            const remoteParticipantReaction = memoizedConvertToVideoTileReaction(participant.reactionState);
            const spotlight = memoizedSpotlight(spotlightedParticipants, toFlatCommunicationIdentifier(participant.identifier));
            return memoizeFn(toFlatCommunicationIdentifier(participant.identifier), displayName, state, participant.isMuted, isScreenSharing, participant.isSpeaking, participant.raisedHand, localUserCanRemoveOthers, remoteParticipantReaction, spotlight, participant.mediaAccess);
        }).sort((a, b) => {
            var _a, _b;
            const nameA = ((_a = a.displayName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
            const nameB = ((_b = b.displayName) === null || _b === void 0 ? void 0 : _b.toLowerCase()) || '';
            if (nameA < nameB) {
                return -1;
            }
            else if (nameA > nameB) {
                return 1;
            }
            else {
                return 0;
            }
        });
    };
    return memoizedConvertAllremoteParticipants(conversionCallback);
};
/**
 * Selects data that drives {@link ParticipantList} component.
 *
 * @public
 */
export const participantListSelector = createSelector([getIdentifier, getDisplayName, getRemoteParticipantsExcludingConsumers, getIsScreenSharingOn, getIsMuted, getLocalParticipantRaisedHand, getRole, getParticipantCount, isHideAttendeeNamesEnabled, getLocalParticipantReactionState, getSpotlightCallFeature, getCapabilities], (userId, displayName, remoteParticipants, isScreenSharingOn, isMuted, raisedHand, role, partitipantCount, isHideAttendeeNamesEnabled, localParticipantReactionState, spotlightCallFeature, capabilities) => {
    const localUserCanRemoveOthers = localUserCanRemoveOthersTrampoline(role);
    const participants = remoteParticipants ? convertRemoteParticipantsToParticipantListParticipants(_updateUserDisplayNames(Object.values(remoteParticipants)), localUserCanRemoveOthers, isHideAttendeeNamesEnabled, role, spotlightCallFeature === null || spotlightCallFeature === void 0 ? void 0 : spotlightCallFeature.spotlightedParticipants) : [];
    participants.push({
        userId: userId,
        displayName: displayName,
        isScreenSharing: isScreenSharingOn,
        isMuted: isMuted,
        raisedHand: raisedHand,
        state: 'Connected',
        // Local participant can never remove themselves.
        isRemovable: false,
        reaction: memoizedConvertToVideoTileReaction(localParticipantReactionState),
        spotlight: memoizedSpotlight(spotlightCallFeature === null || spotlightCallFeature === void 0 ? void 0 : spotlightCallFeature.spotlightedParticipants, userId),
        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
        }
    });
    return {
        participants: participants,
        myUserId: userId
    };
});
const localUserCanRemoveOthersTrampoline = (role) => {
    return role === 'Presenter' || role === 'Unknown' || role === undefined;
};
//# sourceMappingURL=participantListSelector.js.map