import { addPlugin, removePlugin, } from '../../store/pluginSlice';
import config from '../../utils/config';
export default class PluginManager {
    constructor(socketObj, roomName, dispatch, peerId, authToken) {
        this.socketObj = socketObj;
        this.dispatch = dispatch;
        this.roomName = roomName;
        this.plugins = {};
        this.iframes = {};
        this.peerId = peerId;
        this.authToken = authToken;
        this.handleSockets = this.handleSockets.bind(this);
    }
    handleSockets(message) {
        if (!message) {
            return;
        }
        switch (message.type) {
            case 'websocket/enable-plugin':
                this.enablePlugin(message.payload);
                break;
            case 'websocket/disable-plugin':
                this.disablePlugin(message.payload);
                break;
            case 'websocket/plugin-event':
            case 'websocket/plugin-data':
                this.sendIframeEvent(message);
                break;
            default: break;
        }
    }
    sendIframeEvent(message) {
        const views = this.iframes[message.payload.pluginId || message.payload.id];
        if (views) {
            Object.values(views).forEach((view) => {
                if (view.iframe) {
                    view.iframe.injectJavaScript(`window.postMessage(${JSON.stringify(message)});`);
                }
            });
        }
    }
    listenSocketEvents() {
        this.socketObj.emitter.on('socket', this.handleSockets);
        this.getRoomPlugins();
    }
    getRoomPlugins() {
        this.socketObj.sendMessage({ type: 'getRoomState' }, (message) => {
            const roomPlugins = message.payload.roomState.plugins;
            roomPlugins.forEach((p) => this.enablePlugin(p));
        });
    }
    async enablePlugin(plugin) {
        const pluginBase = `${config.apiBase}/v2/plugins`;
        if (this.plugins[plugin.id]) {
            return;
        }
        const pluginReq = await fetch(`${pluginBase}/${plugin.id}`, {
            method: 'GET',
            headers: {
                authorization: `Bearer ${this.authToken}`,
            },
        });
        const pluginDetails = await pluginReq.json();
        const authTokenReq = await fetch(`${pluginBase}/authorize/${plugin.id}`, {
            method: 'POST',
            headers: {
                authorization: `Bearer ${this.authToken}`,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ roomName: this.roomName, peerId: this.peerId }),
        });
        const authToken = (await authTokenReq.json()).data.token;
        const newPlugin = {
            ...pluginDetails.data.plugin,
            authToken,
        };
        this.plugins[plugin.id] = newPlugin;
        this.iframes[plugin.id] = {};
        this.dispatch(addPlugin(newPlugin));
    }
    async disablePlugin(plugin) {
        if (this.plugins[plugin.id]) {
            delete this.plugins[plugin.id];
            this.dispatch(removePlugin(plugin));
        }
    }
    async handleIframeMessage(message) {
        switch (message.type) {
            case 'pluginEvent':
            case 'storePluginData':
            case 'getPluginData':
            case 'getPeerInfo':
            case 'enablePluginForAll':
                this.socketObj.sendMessage(message, (resp) => {
                    this.sendIframeEvent(resp);
                });
                break;
            default:
                break;
        }
    }
    async addIframeView(frame, element, EM) {
        // If view already existed, cleanup the previous event listeners
        if (this.iframes[frame.plugin][frame.view]) {
            this.removeIframeView(frame);
        }
        const listener = (message) => {
            if (!element) {
                return;
            }
            this.handleIframeMessage(message);
        };
        EM.addEventListener(listener);
        this.iframes[frame.plugin][frame.view] = {
            listener,
            iframe: element,
        };
    }
    async removeIframeView(frame) {
        const view = this.iframes[frame.plugin][frame.view];
        if (view) {
            // window.removeEventListener('message', view.listener);
            delete this.iframes[frame.plugin][frame.view];
        }
    }
    async addRoomPlugin(plugin) {
        if (this.plugins[plugin.id]) {
            return;
        }
        await this.socketObj.sendMessage({
            type: 'addPlugin',
            payload: plugin,
        });
    }
    async removeRoomPlugin(plugin) {
        return this.socketObj.sendMessage({
            type: 'removePlugin',
            payload: plugin,
        });
    }
}
//# sourceMappingURL=PluginManager.js.map