import { useEffect, useSyncExternalStore } from "react";
import { getNotificationSubscriptions, subscribeToNotifications, unsubscribeFromNotifications, } from "../services/notificationService";
let snapshot = {
    subscriptions: [],
    initialized: false,
    refreshing: false,
};
let refreshPromise = null;
const listeners = new Set();
function emitChange() {
    listeners.forEach((listener) => listener());
}
function setSnapshot(next) {
    snapshot = typeof next === "function" ? next(snapshot) : next;
    emitChange();
}
function getSnapshot() {
    return snapshot;
}
function subscribe(listener) {
    listeners.add(listener);
    return () => {
        listeners.delete(listener);
    };
}
function matchesTarget(subscription, target) {
    return (subscription.targetType.toLowerCase() === target.targetType.toLowerCase() &&
        subscription.targetId === target.targetId);
}
function upsertSubscription(nextSubscription) {
    setSnapshot((current) => ({
        ...current,
        subscriptions: [
            nextSubscription,
            ...current.subscriptions.filter((subscription) => !matchesTarget(subscription, nextSubscription)),
        ],
    }));
}
export async function refreshNotificationSubscriptions() {
    if (refreshPromise)
        return refreshPromise;
    setSnapshot((current) => ({ ...current, refreshing: true }));
    refreshPromise = (async () => {
        const result = await getNotificationSubscriptions();
        setSnapshot((current) => ({
            subscriptions: result.type === "success" ? (result.data ?? []) : current.subscriptions,
            initialized: true,
            refreshing: false,
        }));
    })().finally(() => {
        refreshPromise = null;
    });
    return refreshPromise;
}
export async function subscribeToNotificationTarget(request) {
    const result = await subscribeToNotifications(request);
    if (result.type === "success" && result.data) {
        upsertSubscription(result.data);
    }
    return result;
}
export async function unsubscribeFromNotificationTarget(request) {
    const result = await unsubscribeFromNotifications(request);
    if (result.type === "success") {
        setSnapshot((current) => ({
            ...current,
            subscriptions: current.subscriptions.filter((subscription) => !matchesTarget(subscription, request)),
        }));
    }
    return result;
}
export function useNotificationSubscriptions() {
    const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
    useEffect(() => {
        if (!state.initialized && !state.refreshing) {
            void refreshNotificationSubscriptions();
        }
    }, [state.initialized, state.refreshing]);
    return {
        subscriptions: state.subscriptions,
        initialized: state.initialized,
        refreshing: state.refreshing,
        refreshSubscriptions: refreshNotificationSubscriptions,
        subscribeToTarget: subscribeToNotificationTarget,
        unsubscribeFromTarget: unsubscribeFromNotificationTarget,
    };
}
//# sourceMappingURL=useNotificationSubscriptions.js.map