(function () {
    let deferredInstallPrompt = null;

    const appIsInstalled = () => {
        return (
            window.matchMedia("(display-mode: standalone)").matches ||
            window.matchMedia("(display-mode: fullscreen)").matches ||
            window.navigator.standalone === true
        );
    };

    const isMobileViewport = () => window.matchMedia("(max-width: 860px)").matches;

    const updateInstallButtons = () => {
        const buttons = Array.from(document.querySelectorAll("[data-install-app]"));
        const canShowInstall = isMobileViewport() && !appIsInstalled();
        buttons.forEach((button) => {
            button.hidden = !canShowInstall;
            button.classList.toggle("is-available", canShowInstall);
        });
    };

    const showInstallHelp = () => {
        const isIOS = /iphone|ipad|ipod/i.test(navigator.userAgent);
        const message = isIOS
            ? "En iPhone/iPad, abri el menu Compartir de Safari y elegi Agregar a pantalla de inicio."
            : "Si el navegador no muestra el instalador, abri el menu del navegador y elegi Instalar app o Agregar a pantalla principal.";
        window.alert(message);
    };

    const urlBase64ToUint8Array = (base64String) => {
        const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
        const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
        const rawData = window.atob(base64);
        const outputArray = new Uint8Array(rawData.length);
        for (let i = 0; i < rawData.length; i += 1) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
    };

    const csrfToken = () => {
        const match = document.cookie.match(/(?:^|; )csrftoken=([^;]+)/);
        return match ? decodeURIComponent(match[1]) : "";
    };

    window.addEventListener("beforeinstallprompt", (event) => {
        event.preventDefault();
        deferredInstallPrompt = event;
        updateInstallButtons();
    });

    window.addEventListener("appinstalled", () => {
        deferredInstallPrompt = null;
        updateInstallButtons();
    });

    document.addEventListener("DOMContentLoaded", () => {
        const toggle = document.querySelector(".nav-toggle");
        const nav = document.querySelector("#main-nav");
        if (toggle && nav) {
            toggle.addEventListener("click", () => {
                const open = nav.classList.toggle("is-open");
                toggle.setAttribute("aria-expanded", String(open));
            });
        }

        const installButtons = Array.from(document.querySelectorAll("[data-install-app]"));
        installButtons.forEach((button) => {
            button.addEventListener("click", () => {
                if (appIsInstalled()) {
                    updateInstallButtons();
                    return;
                }
                if (!deferredInstallPrompt) {
                    showInstallHelp();
                    updateInstallButtons();
                    return;
                }
                deferredInstallPrompt.prompt();
                deferredInstallPrompt.userChoice.then(() => {
                    deferredInstallPrompt = null;
                    updateInstallButtons();
                }).catch(updateInstallButtons);
            });
        });
        updateInstallButtons();
        window.addEventListener("resize", updateInstallButtons);

        if ("serviceWorker" in navigator && window.isSecureContext) {
            navigator.serviceWorker.register("/service-worker.js").catch(() => {});
        }

        const notificationsLink = document.querySelector("[data-notifications-url]");
        const counters = Array.from(document.querySelectorAll("[data-notification-count]"));
        if (!notificationsLink || !counters.length) return;

        const notificationPreferenceKey = "perley:browser-notifications";
        const notificationLastShownKey = "perley:last-browser-notification-id";
        const browserNotificationsEnabled = () => {
            return window.Notification && Notification.permission === "granted";
        };
        const setNotificationStatus = (message) => {
            const status = document.querySelector("[data-desktop-notifications-status]");
            if (status) {
                status.textContent = message;
            }
        };
        const showBrowserNotification = (title, options, fallbackUrl) => {
            if (!window.Notification) {
                setNotificationStatus("Este navegador no soporta notificaciones.");
                window.alert("Este navegador no soporta notificaciones web.");
                return Promise.reject(new Error("Notification API unavailable"));
            }
            if (!window.isSecureContext) {
                setNotificationStatus("Necesita HTTPS para activar notificaciones.");
                window.alert("Las notificaciones web requieren HTTPS.");
                return Promise.reject(new Error("Insecure context"));
            }
            if (Notification.permission !== "granted") {
                setNotificationStatus(`Permiso actual: ${Notification.permission}.`);
                return Promise.reject(new Error(`Notification permission ${Notification.permission}`));
            }
            if ("serviceWorker" in navigator && navigator.serviceWorker.ready) {
                const serviceWorkerReady = Promise.race([
                    navigator.serviceWorker.ready,
                    new Promise((_, reject) => {
                        window.setTimeout(() => reject(new Error("Service worker no listo")), 2500);
                    }),
                ]);
                return serviceWorkerReady
                    .then((registration) => {
                        return registration.showNotification(title, options).then(() => {
                            setNotificationStatus("Notificacion enviada al dispositivo.");
                        });
                    })
                    .catch((error) => {
                        try {
                            const notification = new Notification(title, options);
                            notification.onclick = () => {
                                openNotificationTarget(fallbackUrl || "");
                                notification.close();
                            };
                            setNotificationStatus("Notificacion enviada con fallback del navegador.");
                            return Promise.resolve();
                        } catch (fallbackError) {
                            const message = `${error.message}. Fallback: ${fallbackError.message}`;
                            setNotificationStatus(`No se pudo enviar: ${message}`);
                            return Promise.reject(new Error(message));
                        }
                    });
            }
            const notification = new Notification(title, options);
            notification.onclick = () => {
                openNotificationTarget(fallbackUrl || "");
                notification.close();
            };
            setNotificationStatus("Notificacion enviada con el navegador.");
            return Promise.resolve();
        };
        const openNotificationTarget = (url) => {
            window.focus();
            if (url) {
                window.location.href = url;
            }
        };
        const notifyDevice = (data) => {
            if (!browserNotificationsEnabled()) return;
            const latest = (data.notificaciones || []).find((item) => !item.leida);
            if (!latest) return;
            const latestId = Number(latest.id || 0);
            const lastShownId = Number(localStorage.getItem(notificationLastShownKey) || "0");
            if (latestId && latestId <= lastShownId) return;
            if (latestId) {
                localStorage.setItem(notificationLastShownKey, String(latestId));
            }
            const title = latest.titulo || "Nueva notificacion en PerLEY";
            const options = {
                body: latest.mensaje || latest.causa || "Tenes una nueva notificacion.",
                tag: `perley-${latest.id}`,
                icon: "/static/causas/icons/icon-192.png",
                badge: "/static/causas/icons/icon-192.png",
                data: { url: latest.url || "" },
            };
            showBrowserNotification(title, options, latest.url);
        };
        const refreshNotifications = () => {
            fetch(notificationsLink.dataset.notificationsUrl, {
                headers: { "X-Requested-With": "XMLHttpRequest" },
                credentials: "same-origin",
            })
                .then((response) => {
                    if (!response.ok) throw new Error("notifications");
                    return response.json();
                })
                .then((data) => {
                    const count = Number(data.no_leidas || 0);
                    counters.forEach((counter) => {
                        counter.textContent = String(count);
                        counter.classList.toggle("is-hidden", count === 0);
                    });
                    const latestUnread = (data.notificaciones || []).find((item) => !item.leida);
                    if (latestUnread) {
                        window.dispatchEvent(
                            new CustomEvent("perley:notificaciones", {
                                detail: data,
                            })
                        );
                        notifyDevice(data);
                    }
                })
                .catch(() => {});
        };

        window.setInterval(refreshNotifications, 15000);
        refreshNotifications();

        const permissionPanel = document.querySelector("[data-notifications-permission-panel]");
        const enableNotificationsButton = document.querySelector("[data-enable-desktop-notifications]");
        const notificationsStatus = document.querySelector("[data-desktop-notifications-status]");
        const notificationPromptedKey = "perley:browser-notifications-prompted";
        const canUseNotifications = () => {
            return window.Notification && window.isSecureContext;
        };
        const canUsePush = () => {
            return "serviceWorker" in navigator && "PushManager" in window && canUseNotifications();
        };
        const subscribePushNotifications = () => {
            if (!canUsePush()) {
                return Promise.reject(new Error("Este navegador no soporta Push API."));
            }
            return Notification.requestPermission()
                .then((permission) => {
                    if (permission !== "granted") {
                        throw new Error(`Permiso actual: ${permission}`);
                    }
                    localStorage.setItem(notificationPreferenceKey, "enabled");
                    return navigator.serviceWorker.ready;
                })
                .then((registration) => {
                    return fetch("/api/push/public-key/", { credentials: "same-origin" })
                        .then((response) => response.json())
                        .then(({ publicKey }) => {
                            if (!publicKey) {
                                throw new Error("Falta configurar VAPID en el servidor.");
                            }
                            return registration.pushManager.getSubscription().then((subscription) => {
                                if (subscription) return subscription;
                                return registration.pushManager.subscribe({
                                    userVisibleOnly: true,
                                    applicationServerKey: urlBase64ToUint8Array(publicKey),
                                });
                            });
                        });
                })
                .then((subscription) => {
                    return fetch("/api/push/subscribe/", {
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json",
                            "X-CSRFToken": csrfToken(),
                        },
                        credentials: "same-origin",
                        body: JSON.stringify(subscription),
                    }).then((response) => {
                        if (!response.ok) {
                            throw new Error("No se pudo guardar la suscripcion push.");
                        }
                        return subscription;
                    });
                });
        };
        const updateNotificationStatus = () => {
            if (!notificationsStatus) return;
            if (!window.Notification) {
                notificationsStatus.textContent = "Este navegador no soporta notificaciones.";
            } else if (!window.isSecureContext) {
                notificationsStatus.textContent = "Necesita HTTPS para activar notificaciones.";
            } else if (!("PushManager" in window)) {
                notificationsStatus.textContent = "Este navegador no soporta push real.";
            } else if (Notification.permission === "granted") {
                notificationsStatus.textContent = "Activadas en este dispositivo.";
            } else if (Notification.permission === "denied") {
                notificationsStatus.textContent = "Chrome informa que este sitio tiene notificaciones bloqueadas.";
            } else {
                notificationsStatus.textContent = "Pendientes de activar.";
            }
        };
        const requestBrowserNotifications = (showTestNotification) => {
            if (!canUseNotifications()) {
                updateNotificationStatus();
                if (!window.Notification) {
                    window.alert("Este navegador no soporta notificaciones web.");
                } else if (!window.isSecureContext) {
                    window.alert("Las notificaciones web requieren HTTPS.");
                }
                return;
            }
            if (Notification.permission === "denied") {
                updateNotificationStatus();
                window.alert("Chrome informa que perley.tst.mteam.com.ar tiene notificaciones bloqueadas. En Android revisa: candado de la barra de direcciones > Permisos > Notificaciones > Permitir. Si abriste PerLEY como app instalada, revisa tambien Ajustes de Android > Apps > PerLEY/Chrome > Notificaciones.");
                return;
            }
            if (notificationsStatus) {
                notificationsStatus.textContent = "Solicitando permiso...";
            }
            let handled = false;
            const handlePermission = (permission) => {
                if (handled) return;
                handled = true;
                localStorage.setItem(notificationPromptedKey, "1");
                if (permission === "granted") {
                    localStorage.setItem(notificationPreferenceKey, "enabled");
                    if (showTestNotification) {
                        const title = "PerLEY";
                        const options = {
                            body: "Notificaciones activadas en este dispositivo.",
                            icon: "/static/causas/icons/icon-192.png",
                            tag: "perley-enabled",
                        };
                        showBrowserNotification(title, options).catch(() => {});
                    }
                } else {
                    window.alert(`El navegador no concedio el permiso. Estado: ${permission}.`);
                }
                updateNotificationStatus();
            };

            try {
                const permissionRequest = Notification.requestPermission(handlePermission);
                if (permissionRequest && typeof permissionRequest.then === "function") {
                    permissionRequest.then(handlePermission).catch(updateNotificationStatus);
                }
            } catch (_error) {
                handled = true;
                if (notificationsStatus) {
                    notificationsStatus.textContent = "El navegador no permitio solicitar notificaciones desde esta pantalla.";
                }
                return;
            }
            window.setTimeout(() => {
                if (handled) return;
                localStorage.setItem(notificationPromptedKey, "1");
                if (notificationsStatus) {
                    notificationsStatus.textContent = "El navegador no mostro el permiso. Revisa los permisos del sitio o instalala como app.";
                }
            }, 1200);
        };

        if (enableNotificationsButton) {
            enableNotificationsButton.addEventListener("click", () => {
                if (notificationsStatus) {
                    notificationsStatus.textContent = "Activando push...";
                }
                subscribePushNotifications()
                    .then(() => fetch("/api/push/test/", {
                        method: "POST",
                        headers: {"X-CSRFToken": csrfToken()},
                        credentials: "same-origin",
                    }))
                    .then(() => {
                        if (notificationsStatus) {
                            notificationsStatus.textContent = "Push activado en este dispositivo.";
                        }
                    })
                    .catch((error) => {
                        if (notificationsStatus) {
                            notificationsStatus.textContent = error.message;
                        }
                        requestBrowserNotifications(true);
                    });
            });
            updateNotificationStatus();
        }

        const testNotificationsButton = document.querySelector("[data-test-desktop-notifications]");
        if (testNotificationsButton) {
            testNotificationsButton.addEventListener("click", () => {
                setNotificationStatus("Probando notificacion...");
                if (!browserNotificationsEnabled()) {
                    requestBrowserNotifications(true);
                    return;
                }
                fetch("/api/push/test/", {
                    method: "POST",
                    headers: {"X-CSRFToken": csrfToken()},
                    credentials: "same-origin",
                })
                    .then((response) => response.json())
                    .then((data) => {
                        if (data.sent > 0) {
                            setNotificationStatus("Push de prueba enviado desde el servidor.");
                            return;
                        }
                        return showBrowserNotification("PerLEY", {
                            body: "Prueba de notificacion del dispositivo.",
                            icon: "/static/causas/icons/icon-192.png",
                            tag: `perley-test-${Date.now()}`,
                        });
                    })
                    .catch((error) => {
                        setNotificationStatus(`No se pudo enviar: ${error.message}`);
                        window.alert(`No se pudo enviar la notificacion: ${error.message}`);
                    });
            });
        }

        if (permissionPanel && canUseNotifications() && Notification.permission === "default") {
            localStorage.removeItem(notificationPromptedKey);
        }
    });
})();
