// retoor <retoor@molodetz.nl>

import { Http } from "./Http.js";

export class PushManager {
    constructor() {
        this.supported = "serviceWorker" in navigator && "PushManager" in window && "Notification" in window;
        if (!this.supported) {
            return;
        }
        this.userUid = document.body.dataset.userUid || "";
        this.triggers = Array.from(document.querySelectorAll("[data-push-enable]"));
        this.bindTriggers();
        this.refreshTriggerVisibility();
        this.register(true).catch((error) => console.error("Push silent register failed:", error));
    }

    bindTriggers() {
        this.triggers.forEach((trigger) => {
            trigger.addEventListener("click", (event) => {
                event.preventDefault();
                this.optIn();
            });
        });
    }

    refreshTriggerVisibility() {
        const granted = Notification.permission === "granted";
        this.triggers.forEach((trigger) => {
            trigger.hidden = granted;
        });
    }

    async optIn() {
        const permission = await Notification.requestPermission();
        if (permission === "granted") {
            await this.register(false);
        }
    }

    async register(silent) {
        try {
            const registration = await navigator.serviceWorker.register("/service-worker.js");
            await registration.update();
            await navigator.serviceWorker.ready;

            if (Notification.permission !== "granted") {
                this.refreshTriggerVisibility();
                return;
            }

            if (!this.userUid) {
                return;
            }

            const keyData = await Http.getJson("/push.json");
            if (!keyData.publicKey) {
                return;
            }
            const applicationServerKey = Uint8Array.from(atob(keyData.publicKey), (c) => c.charCodeAt(0));

            const subscription = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: applicationServerKey,
            });

            await Http.postJson("/push.json", subscription.toJSON());

            this.refreshTriggerVisibility();
        } catch (error) {
            if (error.status === 401) {
                return;
            }
            console.error("Error registering push notifications:", error);
            if (!silent) {
                window.app.dialog.alert({
                    title: "Push notifications",
                    message: "Enabling push notifications failed. Please check your browser settings and try again.\n\n" + error,
                });
            }
        }
    }
}
