import { initializeApp } from "https://www.gstatic.com/firebasejs/9.9.2/firebase-app.js";
import { getMessaging, getToken, onMessage } from "https://www.gstatic.com/firebasejs/9.9.2/firebase-messaging.js";

class FirebaseController {
    sdk;
    app;
    messaging;
    firebaseConfig;

    constructor(firebaseConfig) {
        this.sdk = new IframeGuestSDK();
        this.firebaseConfig = firebaseConfig;
	}

    initialize() {
        if (!this.isEmbedded()) {
            this.app = initializeApp(this.firebaseConfig);
            this.messaging = getMessaging(this.app);
        }
    }

    async setNotifications() {
        sessionStorage['STCMBackEnd:notifications_activated'] = '0';
        if (!this.isEmbedded()) {
            const permission = await this.promptNotificationPermission();
            return permission;
        } else {
            let permission = await this.sdk.hasNotificationsEnabled();
            if (!permission) {
                permission = await this.sdk.promptNotificationPermission();
            }
            return permission;
        }
    }

    async promptNotificationPermission() {
        return new Promise((resolve) => {
            if (!("Notification" in window)) {
                // El navegador no admite notificaciones
                resolve(false);
            } else if (Notification.permission === "granted") {
                // Los permisos ya se han otorgado previamente
                sessionStorage['STCMBackEnd:notifications_activated'] = '1';
                resolve(true);
            } else {
                pf.utils.showInfoDialogAcceptCancel(
                    "Activar Notificaciones",
                    "Para el correcto funcionamiento de la aplicación se requiere la activación de notificaciones. ¿Desea permitir la activación de notificaciones?",
                    { accept: { text: "Permitir" }, cancel: { text: "Cancelar" }},
                    async function() {
                        const permission = await Notification.requestPermission();
                        if (permission === "granted") {
                            sessionStorage['STCMBackEnd:notifications_activated'] = '1';
                            resolve(true);
                        } else {
                            resolve(false);
                        }
                    },
                    function() {
                        resolve(false);
                    }
                );
            }
        });
    }

    async getFirebaseToken() {
        const _self = this;
        if (!this.isEmbedded()) {
            try {
                const currentToken = await getToken(this.messaging, { vapidKey: stcm.const.firebaseKey});
                if (currentToken) {
                    _self.registerFirebaseToken(currentToken);
                    return true;
                } else {
                    //console.log('No registration token available. Request permission to generate one.');
                    return false;
                }
            } catch (err) {
                //console.log('An error occurred while retrieving token. ', err);
                return false;
            }
        } else {
            return this.sdk.getFirebaseToken();
        }
    }

    registerFirebaseToken(token) {
        let userData = null;
        try { userData = JSON.parse(sessionStorage['STCMBackEnd:appUserDetails']); } catch (error) {}
        if (!userData) {
            return true;
            userData = JSON.parse(sessionStorage['STCMBackEnd:user'] || "{}");
        }
        let userEmail = userData ? (userData.email || userData.token || "") : "";
        
        let parameters = {
            email: userEmail,
            platform: 'Web',
            deviceId: token
        };

        CommunityManagement.ajax.doAjax('setTokenDeviceForPush_SaaS', parameters, false, function() {});
    }

    setOnFirebaseMessage() {
        if (!this.isEmbedded()) {
            onMessage(this.messaging, (payload) => {
                stcmbackend.communymanagement.onReceivedMessageFirebase(payload,false);
            });
        } else {
            this.sdk.setOnFirebaseMessage();
        }
    }

    isEmbedded() {
        return window.self !== window.top; 
    }

    isNotificationSupported() {
        if (!window.Notification) return false;
        return true;
    }

    hasNotificationsEnabled() {
        if (!this.isNotificationSupported() && Notification.permission !== "granted") return false;
        return true;
    }
}

class IframeGuestSDK {
    async hasNotificationsEnabled() {
        return new Promise((resolve) => {
            function messageListener(event) {
                if (event.data && event.data.action === "hasNotificationsEnabledResponse") {
                    const msgData = event.data.data;
                    
                    window.removeEventListener("message", messageListener);
                    
                    if (msgData.permission) {
                        sessionStorage['STCMBackEnd:notifications_activated'] = '1';
                        resolve(msgData.permission);
                    } else {
                        resolve(false);
                    }
                } else {
                    resolve(false);
                }
            }

            setTimeout(function() {
                window.addEventListener("message", messageListener);
                window.parent.postMessage({ action: "hasNotificationsEnabled" }, "*");
            }, 500)            
        });
    }
    
    async promptNotificationPermission() {
        return new Promise((resolve) => {
            function messageListener(event) {
                if (event.data && event.data.action === "promptNotificationPermissionResponse") {
                    const msgData = event.data.data;
                    window.removeEventListener("message", messageListener);
                    if (msgData.permission) {
                        sessionStorage['STCMBackEnd:notifications_activated'] = '1';
                        resolve(msgData.permission);
                    } else {
                        resolve(false);
                    }
                } else {
                    resolve(false);
                }
            }

            pf.utils.showInfoDialogAcceptCancel(
                "Activar Notificaciones",
                "Para el correcto funcionamiento de la aplicación se requiere la activación de notificaciones. ¿Desea permitir la activación de notificaciones?",
                { accept: { text: "Permitir" }, cancel: { text: "Cancelar" }},
                async function() {
                    window.addEventListener("message", messageListener);
                    window.parent.postMessage({ action: "promptNotificationPermission" }, "*");
                },
                function() {
                    resolve(false);
                }
            );
        });
    }

    async getFirebaseToken() {
        return new Promise((resolve) => {
            function messageListener(event) {
                if (event.data && event.data.action === "getFirebaseTokenResponse") {
                    const msgData = event.data.data;

                    window.removeEventListener("message", messageListener);
                        
                    if (event.data.code==200) {
                        let firebaseCtrl = new FirebaseController({});
                        firebaseCtrl.registerFirebaseToken(msgData.token);
                        resolve(true);
                    } else {
                        resolve(false);
                    }
                } else {
                    resolve(false);
                }
            }

            window.addEventListener("message", messageListener);
            window.parent.postMessage({ action: "getFirebaseToken" }, "*");
        });
    }

    setOnFirebaseMessage() {
        function messageListener(event) {
            if (!event.data || !event.data.action) return;
            const action = event.data.action;
            const msgData = event.data.data;

            if (action=="firebaseNotification") {
                stcmbackend.communymanagement.onReceivedMessageFirebase(msgData,false);
            }
        }

        window.addEventListener("message", messageListener);
    }
}

function notificationsNotActivated() {
    sessionStorage['STCMBackEnd:notifications_activated'] = '0';
    let textTitle = 'Permisos de notificaciones';
    let textContent = 'Se ha detectado que no tiene activados los permisos para recibir notificaciones. Por favor revise la configuración de su navegador y habilite las notificaciones en este sitio para utilizar la aplicación.';
    pf.utils.showInfoDialog(textTitle, textContent, 'Aceptar');
}

// Initialize Firebase and handle notifications
// Initialize Firebase and handle notifications
const firebaseConfig = stcm.const.firebaseConfig;
const firebaseCtrl = new FirebaseController(firebaseConfig);

const maxTries = 2;
const retryDelay = 1000;

const tryOperationWithRetries = async (operation, maxTries, retryDelay) => {
    for (let numTries = 0; numTries < maxTries; numTries++) {
        if (await operation()) {
            return true;
        }

        await new Promise(resolve => setTimeout(resolve, retryDelay));
    }
    return false;
};

const initializeFirebase = async () => {
    firebaseCtrl.initialize();

    const notificationPermissionGranted = await tryOperationWithRetries(
        () => firebaseCtrl.setNotifications(),
        maxTries
    );

    if (notificationPermissionGranted) {
        const fbTokenObtained = await tryOperationWithRetries(
            () => firebaseCtrl.getFirebaseToken(),
            maxTries,
            retryDelay
        );

        if (fbTokenObtained) {
            firebaseCtrl.setOnFirebaseMessage();
        } else {
            notificationsNotActivated();
        }
    } else {
        notificationsNotActivated();
    }
};

document.addEventListener("DOMContentLoaded", () => {
    initializeFirebase();
});