import { act } from "@testing-library/react";
import { BASE_MEDIA_QUERY_LIST, matchDesktop } from "../mocks/match-media.js";
/**
 * Used to create a `spyOn(window, "matchMedia")` without knowing the test
 * framework.
 *
 * @example Setup Test Framework
 * ```tsx
 * export function spyOnMatchMedia(
 *   defaultMatch: MatchMediaMatcher = matchDesktop
 * ): jest.SpiedFunction<typeof window.matchMedia> & MatchMediaChangeViewport {
 *   return createMatchMediaSpy(jest.spyOn(window, "matchMedia"), defaultMatch);
 * }
 * ```
 *
 * NOTE: The `spyOnMatchMedia` function **must** not call the `.spyOn`
 * immediately to work correctly. The spy needs to be invoked whenever this is
 * called instead. For example, this is bad and will fail:
 *
 * @example Bad Example
 * ```tsx
 * export const spyOnMatchMedia = createMatchMediaSpy.bind(null, jest.spy(window, "matchMedia"));
 * ```
 *
 * This is mostly a reminder to myself since I wanted something like the
 * following code, but failed:
 *
 * ```ts
 * export const spyOnMatchMedia = createMatchMediaSpy(jest.spyOn(window, "matchMedia"));
 * ```
 *
 * @since 6.0.0
 * @internal
 */ export function createMatchMediaSpy(matchMediaSpy, defaultMatch = matchDesktop) {
    const listeners = new Map();
    const matchMedia = matchMediaSpy.mockImplementation((query)=>({
            ...BASE_MEDIA_QUERY_LIST,
            addEventListener (type, listener) {
                /* c8 ignore start */ if (typeof listener !== "function" || type !== "change") {
                    return;
                }
                /* c8 ignore stop */ listeners.set(query, listener);
            },
            removeEventListener (type, listener) {
                /* c8 ignore start */ if (typeof listener !== "function" || type !== "change") {
                    return;
                }
                /* c8 ignore stop */ listeners.delete(query);
            },
            matches: defaultMatch(query)
        }));
    const changeViewport = (matcher, disableAct = false)=>{
        const update = ()=>{
            window.dispatchEvent(new Event("resize"));
            const event = new Event("change");
            listeners.forEach((listener, query)=>{
                listener({
                    ...event,
                    media: "",
                    matches: matcher(query)
                });
            });
        };
        if (disableAct) {
            update();
        } else {
            act(update);
        }
    };
    const mock = matchMedia;
    mock.changeViewport = changeViewport;
    return mock;
}

//# sourceMappingURL=createMatchMediaSpy.js.map