// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
 * @private
 */
export class RemoteVideoStreamSubscriber {
    constructor(callIdRef, participantKey, remoteVideoStream, context) {
        this.subscribe = () => {
            this._remoteVideoStream.on('isAvailableChanged', this.isAvailableChanged);
            this._remoteVideoStream.on('isReceivingChanged', this.isReceivingChanged);
            this._remoteVideoStream.on('sizeChanged', this.isSizeChanged);
            this.checkAndUpdateScreenShareState();
        };
        this.unsubscribe = () => {
            this._remoteVideoStream.off('isAvailableChanged', this.isAvailableChanged);
            this._remoteVideoStream.off('isReceivingChanged', this.isReceivingChanged);
            this._remoteVideoStream.off('sizeChanged', this.isSizeChanged);
        };
        this.includesActiveScreenShareStream = (streams) => {
            for (const stream of Object.values(streams)) {
                if (stream.mediaStreamType === 'ScreenSharing' && stream.isAvailable) {
                    return true;
                }
            }
            return false;
        };
        /**
         * Update the state with the active screen share stream. If there is an existing stream will overwrite it if this one
         * is active (newer stream takes priority). If there is an existing stream and this one is set to unavailable, and the
         * existing stream is different participant, then don't set the active screen share stream to undefined, else set it
         * to undefined.
         */
        this.checkAndUpdateScreenShareState = () => {
            var _a, _b, _c;
            if (this._remoteVideoStream.mediaStreamType !== 'ScreenSharing') {
                return;
            }
            if (this._remoteVideoStream.isAvailable) {
                this._context.setCallScreenShareParticipant(this._callIdRef.callId, this._participantKey);
                return;
            }
            const existingScreenShare = (_a = this._context.getState().calls[this._callIdRef.callId]) === null || _a === void 0 ? void 0 : _a.screenShareRemoteParticipant;
            // If somehow we end up with an event where a RemoteParticipant's ScreenShare stream is set to
            // unavailable but there exists already another different participant actively sharing, and they are still
            // sharing then this event shouldn't set the screenShareRemoteParticipant to undefined.
            if (!existingScreenShare || existingScreenShare === this._participantKey) {
                this._context.setCallScreenShareParticipant(this._callIdRef.callId, undefined);
                return;
            }
            const streams = (_c = (_b = this._context.getState().calls[this._callIdRef.callId]) === null || _b === void 0 ? void 0 : _b.remoteParticipants[existingScreenShare]) === null || _c === void 0 ? void 0 : _c.videoStreams;
            if (!streams) {
                this._context.setCallScreenShareParticipant(this._callIdRef.callId, undefined);
                return;
            }
            // If the existing ScreenShare that is not owned by the current RemoteParticipant is still active, don't
            // overwrite it with undefined. So only overwrite if it is not active.
            if (!this.includesActiveScreenShareStream(streams)) {
                this._context.setCallScreenShareParticipant(this._callIdRef.callId, undefined);
                return;
            }
        };
        this.isAvailableChanged = () => {
            this._context.setRemoteVideoStreamIsAvailable(this._callIdRef.callId, this._participantKey, this._remoteVideoStream.id, this._remoteVideoStream.isAvailable);
            this.checkAndUpdateScreenShareState();
        };
        this.isReceivingChanged = () => {
            this._context.setRemoteVideoStreamIsReceiving(this._callIdRef.callId, this._participantKey, this._remoteVideoStream.id, this._remoteVideoStream.isReceiving);
        };
        this.isSizeChanged = () => {
            var _a, _b, _c, _d, _e, _f, _g;
            if (((_a = this._remoteVideoStream) === null || _a === void 0 ? void 0 : _a.size.width) === 0 && ((_b = this._remoteVideoStream) === null || _b === void 0 ? void 0 : _b.size.height) === 0) {
                return;
            }
            const streamSize = (_e = (_d = (_c = this._context.getState().calls[this._callIdRef.callId]) === null || _c === void 0 ? void 0 : _c.remoteParticipants[this._participantKey]) === null || _d === void 0 ? void 0 : _d.videoStreams[this._remoteVideoStream.id]) === null || _e === void 0 ? void 0 : _e.streamSize;
            const existingAspectRatio = streamSize ? streamSize.width / streamSize.height : undefined;
            const newAspectRatio = ((_f = this._remoteVideoStream) === null || _f === void 0 ? void 0 : _f.size.width) / ((_g = this._remoteVideoStream) === null || _g === void 0 ? void 0 : _g.size.height);
            if (!streamSize || existingAspectRatio !== newAspectRatio) {
                this._context.setRemoteVideoStreamSize(this._callIdRef.callId, this._participantKey, this._remoteVideoStream.id, this._remoteVideoStream.size);
            }
        };
        this._callIdRef = callIdRef;
        this._participantKey = participantKey;
        this._remoteVideoStream = remoteVideoStream;
        this._context = context;
        this.subscribe();
    }
}
//# sourceMappingURL=RemoteVideoStreamSubscriber.js.map