import { useEffect } from 'react';
import { useSyncedRef } from '../useSyncedRef/index.js';
import { isBrowser } from '../util/const.js';
let observerSingleton;
function getResizeObserver() {
    if (!isBrowser)
        return undefined;
    if (observerSingleton)
        return observerSingleton;
    const callbacks = new Map();
    const observer = new ResizeObserver((entries) => {
        for (const entry of entries)
            callbacks.get(entry.target)?.forEach((cb) => setTimeout(() => {
                cb(entry);
            }, 0));
    });
    observerSingleton = {
        observer,
        subscribe(target, callback) {
            let cbs = callbacks.get(target);
            if (!cbs) {
                cbs = new Set();
                callbacks.set(target, cbs);
                observer.observe(target);
            }
            cbs.add(callback);
        },
        unsubscribe(target, callback) {
            const cbs = callbacks.get(target);
            if (cbs) {
                cbs.delete(callback);
                if (cbs.size === 0) {
                    callbacks.delete(target);
                    observer.unobserve(target);
                }
            }
        },
    };
    return observerSingleton;
}
export function useResizeObserver(target, callback, enabled = true) {
    const ro = enabled && getResizeObserver();
    const cb = useSyncedRef(callback);
    const tgt = target && 'current' in target ? target.current : target;
    useEffect(() => {
        const tgt = target && 'current' in target ? target.current : target;
        if (!ro || !tgt)
            return;
        let subscribed = true;
        const handler = (...args) => {
            if (subscribed) {
                cb.current(...args);
            }
        };
        ro.subscribe(tgt, handler);
        return () => {
            subscribed = false;
            ro.unsubscribe(tgt, handler);
        };
    }, [tgt, ro]);
}
