'use client';
import * as React from 'react';
import { useFluent_unstable as useFluent } from '@fluentui/react-shared-contexts';
import { isHTMLElement } from '@fluentui/react-utilities';
export function useOptionWalker(options) {
    const { matchOption } = options;
    const { targetDocument } = useFluent();
    const treeWalkerRef = React.useRef(null);
    const listboxRef = React.useRef(null);
    const optionFilter = React.useCallback((node)=>{
        if (isHTMLElement(node) && matchOption(node)) {
            return NodeFilter.FILTER_ACCEPT;
        }
        return NodeFilter.FILTER_SKIP;
    }, [
        matchOption
    ]);
    const setListbox = React.useCallback((el)=>{
        if (el && targetDocument) {
            listboxRef.current = el;
            treeWalkerRef.current = targetDocument.createTreeWalker(el, NodeFilter.SHOW_ELEMENT, optionFilter);
        } else {
            listboxRef.current = null;
            treeWalkerRef.current = null;
        }
    }, [
        targetDocument,
        optionFilter
    ]);
    const optionWalker = React.useMemo(()=>({
            first: ()=>{
                if (!treeWalkerRef.current || !listboxRef.current) {
                    return null;
                }
                treeWalkerRef.current.currentNode = listboxRef.current;
                return treeWalkerRef.current.firstChild();
            },
            last: ()=>{
                if (!treeWalkerRef.current || !listboxRef.current) {
                    return null;
                }
                treeWalkerRef.current.currentNode = listboxRef.current;
                return treeWalkerRef.current.lastChild();
            },
            next: ()=>{
                if (!treeWalkerRef.current) {
                    return null;
                }
                return treeWalkerRef.current.nextNode();
            },
            prev: ()=>{
                if (!treeWalkerRef.current) {
                    return null;
                }
                return treeWalkerRef.current.previousNode();
            },
            find: (predicate, startFrom)=>{
                if (!treeWalkerRef.current || !listboxRef.current) {
                    return null;
                }
                const start = startFrom ? targetDocument === null || targetDocument === void 0 ? void 0 : targetDocument.getElementById(startFrom) : null;
                treeWalkerRef.current.currentNode = start !== null && start !== void 0 ? start : listboxRef.current;
                let cur = treeWalkerRef.current.currentNode;
                while(cur && !predicate(cur.id)){
                    cur = treeWalkerRef.current.nextNode();
                }
                return cur;
            },
            setCurrent: (el)=>{
                if (!treeWalkerRef.current) {
                    return;
                }
                treeWalkerRef.current.currentNode = el;
            }
        }), [
        targetDocument
    ]);
    return {
        optionWalker,
        listboxCallbackRef: setListbox
    };
}
