import { useEffect, useState } from 'react';
import { isBrowser } from '../util/const.js';
const queriesMap = new Map();
const createQueryEntry = (query) => {
    const mql = matchMedia(query);
    const dispatchers = new Set();
    const listener = () => {
        for (const d of dispatchers) {
            d(mql.matches);
        }
    };
    if (mql.addEventListener)
        mql.addEventListener('change', listener, { passive: true });
    else
        mql.addListener(listener);
    return {
        mql,
        dispatchers,
        listener,
    };
};
const querySubscribe = (query, setState) => {
    let entry = queriesMap.get(query);
    if (!entry) {
        entry = createQueryEntry(query);
        queriesMap.set(query, entry);
    }
    entry.dispatchers.add(setState);
    setState(entry.mql.matches);
};
const queryUnsubscribe = (query, setState) => {
    const entry = queriesMap.get(query);
    if (entry) {
        const { mql, dispatchers, listener } = entry;
        dispatchers.delete(setState);
        if (dispatchers.size === 0) {
            queriesMap.delete(query);
            if (mql.removeEventListener)
                mql.removeEventListener('change', listener);
            else
                mql.removeListener(listener);
        }
    }
};
export function useMediaQuery(query, options = {}) {
    let { initializeWithValue = true } = options;
    if (!isBrowser) {
        initializeWithValue = false;
    }
    const [state, setState] = useState(() => {
        if (initializeWithValue) {
            let entry = queriesMap.get(query);
            if (!entry) {
                entry = createQueryEntry(query);
                queriesMap.set(query, entry);
            }
            return entry.mql.matches;
        }
    });
    useEffect(() => {
        querySubscribe(query, setState);
        return () => {
            queryUnsubscribe(query, setState);
        };
    }, [query]);
    return state;
}
