// 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 { toFlatCommunicationIdentifier } from "../../../../../acs-ui-common/src";
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Facade around the CallWithChatAdapter to satisfy the chat adapter interface.
 *
 * @private
 */
export class CallWithChatBackedChatAdapter {
    constructor(callWithChatAdapter) {
        // For onStateChange we must convert CallWithChat state to chat state. This involves creating a new handler to be passed into the onStateChange.
        // In order to unsubscribe the handler when offStateChange is called we must have a mapping of the original handler to the newly created handler.
        this.eventStore = new Map();
        this.fetchInitialData = () => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.fetchInitialData(); });
        // due to a bug in babel, we can't use arrow function here
        // affecting conditional-compile-remove(attachment-upload)
        // have to bind this since the scope of 'this' is lost when the function is passed as a callback
        this.sendMessageHandler = function (content) {
            return __awaiter(this, void 0, void 0, function* () {
                yield this.callWithChatAdapter.sendMessage(content);
            });
        };
        this.sendMessage = this.sendMessageHandler.bind(this);
        this.sendReadReceipt = (chatMessageId) => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.sendReadReceipt(chatMessageId); });
        this.sendTypingIndicator = () => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.sendTypingIndicator(); });
        this.removeParticipant = (userId) => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.removeParticipant(userId); });
        this.loadPreviousChatMessages = (messagesToLoad) => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.loadPreviousChatMessages(messagesToLoad); });
        this.dispose = () => this.callWithChatAdapter.dispose();
        this.onStateChange = (handler) => {
            const convertedHandler = (state) => {
                !!state.chat && handler(chatAdapterStateFromCallWithChatAdapterState(state));
            };
            this.callWithChatAdapter.onStateChange(convertedHandler);
            this.eventStore.set(handler, convertedHandler);
        };
        this.offStateChange = (handler) => {
            const convertedHandler = this.eventStore.get(handler);
            convertedHandler && this.callWithChatAdapter.offStateChange(convertedHandler);
        };
        this.getState = () => chatAdapterStateFromCallWithChatAdapterState(this.callWithChatAdapter.getState());
        /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
        this.on = (event, listener) => {
            switch (event) {
                case 'error':
                    return this.callWithChatAdapter.on('chatError', listener);
                case 'participantsAdded':
                    return this.callWithChatAdapter.on('chatParticipantsAdded', listener);
                case 'participantsRemoved':
                    return this.callWithChatAdapter.on('chatParticipantsRemoved', listener);
                default:
                    return this.callWithChatAdapter.on(event, listener);
            }
        };
        this.off = (event, listener) => {
            switch (event) {
                case 'error':
                    return this.callWithChatAdapter.off('chatError', listener);
                case 'participantsAdded':
                    return this.callWithChatAdapter.off('chatParticipantsAdded', listener);
                case 'participantsRemoved':
                    return this.callWithChatAdapter.off('chatParticipantsRemoved', listener);
                default:
                    return this.callWithChatAdapter.off(event, listener);
            }
        };
        // due to a bug in babel, we can't use arrow function here
        // affecting conditional-compile-remove(attachment-upload)
        // have to bind this since the scope of 'this' is lost when the function is passed as a callback
        this.updateMessageHandler = function (messageId, content, options) {
            return __awaiter(this, void 0, void 0, function* () {
                yield this.callWithChatAdapter.updateMessage(messageId, content, options);
            });
        };
        this.updateMessage = this.updateMessageHandler.bind(this);
        this.deleteMessage = (messageId) => __awaiter(this, void 0, void 0, function* () { return yield this.callWithChatAdapter.deleteMessage(messageId); });
        this.clearErrors = (errorTypes) => {
            throw new Error(`Method not supported in CallWithChatComposite.`);
        };
        this.setTopic = (topicName) => __awaiter(this, void 0, void 0, function* () {
            throw new Error(`Chat Topics are not supported in CallWithChatComposite.`);
        });
        this.callWithChatAdapter = callWithChatAdapter;
    }
    downloadResourceToCache(resourceDetails) {
        return __awaiter(this, void 0, void 0, function* () {
            this.callWithChatAdapter.downloadResourceToCache(resourceDetails);
        });
    }
    removeResourceFromCache(resourceDetails) {
        this.callWithChatAdapter.removeResourceFromCache(resourceDetails);
    }
}
function chatAdapterStateFromCallWithChatAdapterState(callWithChatAdapterState) {
    if (!callWithChatAdapterState.chat) {
        // Return some empty state if chat is not initialized yet
        return {
            userId: callWithChatAdapterState.userId,
            displayName: callWithChatAdapterState.displayName || '',
            thread: {
                chatMessages: {},
                participants: {
                    [toFlatCommunicationIdentifier(callWithChatAdapterState.userId)]: {
                        id: callWithChatAdapterState.userId
                    }
                },
                threadId: '',
                readReceipts: [],
                typingIndicators: [],
                latestReadTime: new Date()
            },
            latestErrors: callWithChatAdapterState.latestChatErrors
        };
    }
    return {
        userId: callWithChatAdapterState.userId,
        displayName: callWithChatAdapterState.displayName || '',
        thread: callWithChatAdapterState.chat,
        latestErrors: callWithChatAdapterState.latestChatErrors
    };
}
//# sourceMappingURL=CallWithChatBackedChatAdapter.js.map