import { useEffect, useCallback } from 'react';
import { getAllPopovers, isInstance, normalizeTargets } from '../utils';
import useConfiguration from './useConfiguration';
/**
 * @example useOuterEvent(eventName, [nodes], handler = () => { doSomething; });
 * @param eventName The type of event to trigger the handler function on. Reference [DocumentEventMap](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.documenteventmap.html) for a list of valid events.
 * @param nodes An array of Nodes or Refs to Nodes to attach the eventName to.
 * @param handler The function that is called when the given event occurs.
 */
const useOuterEvent = (eventName, nodes, handler) => {
    const { portalTarget } = useConfiguration();
    const windowContext = portalTarget?.ownerDocument?.defaultView || window;
    const onEvent = useCallback(event => {
        const path = event.composedPath();
        const target = path[0];
        if (!isInstance(target, Node))
            return;
        let childIdx = 0;
        let parentIdx = 1;
        while (!isInstance(path[childIdx], Document)) {
            const child = path[childIdx];
            const parent = path[parentIdx];
            if (!child || !parent)
                return;
            if (isInstance(parent, DocumentFragment) || isInstance(parent, Document)) {
                if (!isInstance(child, Node) || !parent.contains(child))
                    return;
                childIdx = parentIdx;
            }
            else if (isInstance(child, DocumentFragment)) {
                if (!isInstance(parent, Element) || parent.shadowRoot !== child)
                    return;
                childIdx = parentIdx;
            }
            parentIdx += 1;
        }
        const normalizedNodes = normalizeTargets(nodes).flatMap(node => {
            if (!isInstance(node, Element) &&
                !isInstance(node, Document) &&
                !isInstance(node, DocumentFragment)) {
                return [node];
            }
            return [node, ...getAllPopovers(node)];
        });
        if (normalizedNodes.every(node => {
            return node !== target && !node.contains(target);
        })) {
            handler(event);
        }
    }, [...nodes, handler]);
    useEffect(() => {
        const eventNames = Array.isArray(eventName) ? eventName : [eventName];
        eventNames.forEach(event => windowContext?.document?.addEventListener(event, onEvent));
        return () => {
            eventNames.forEach(event => windowContext?.document?.removeEventListener(event, onEvent));
        };
    }, [eventName, onEvent]);
};
export default useOuterEvent;
//# sourceMappingURL=useOuterEvent.js.map