"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = (exports1, definition)=>{
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
    __webpack_require__.r = (exports1)=>{
        if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    Toolbox: ()=>Toolbox
});
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
const index_cjs_namespaceObject = require("../../hooks/index.cjs");
const external_layouts_index_cjs_namespaceObject = require("../../layouts/index.cjs");
const external_react_namespaceObject = require("react");
const external_i18n_index_cjs_namespaceObject = require("../../../i18n/index.cjs");
const external_react_window_namespaceObject = require("react-window");
const external_constants_cjs_namespaceObject = require("../../constants.cjs");
const external_Header_cjs_namespaceObject = require("./Header.cjs");
const external_ListView_cjs_namespaceObject = require("./ListView.cjs");
const external_QuickActionsRow_cjs_namespaceObject = require("./QuickActionsRow.cjs");
const external_SearchBox_cjs_namespaceObject = require("./SearchBox.cjs");
const external_Toolbox_styles_cjs_namespaceObject = require("./Toolbox.styles.cjs");
const TRANSITION_DURATION = 150;
const SEARCH_BAR_INDEX = -1;
function findItemById(items, id) {
    const queue = [
        ...items
    ];
    const visited = new Set(items.map((item)=>item.id));
    let qIndex = 0;
    while(qIndex < queue.length){
        const item = queue[qIndex++];
        if (item.id === id) return item;
        if (!item.children || 'function' == typeof item.children) continue;
        for (const child of item.children)if (!visited.has(child.id)) {
            visited.add(child.id);
            queue.push(child);
        }
    }
    return null;
}
function getNextSelectableIndex(renderedItems, currentIndex, direction) {
    const numericDirection = 'up' === direction ? -1 : 1;
    let next = currentIndex + numericDirection;
    while(next >= 0 && next < renderedItems.length){
        if (renderedItems[next]?.type === 'item') return next;
        next += numericDirection;
    }
    return SEARCH_BAR_INDEX;
}
function getFirstSelectableIndex(renderedItems) {
    for(let i = 0; i < renderedItems.length; i++)if (renderedItems[i]?.type === 'item') return i;
    return SEARCH_BAR_INDEX;
}
function getLastSelectableIndex(renderedItems) {
    for(let i = renderedItems.length - 1; i >= 0; i--)if (renderedItems[i]?.type === 'item') return i;
    return SEARCH_BAR_INDEX;
}
function searchLeafItems(items, query) {
    const results = [];
    for (const item of items)if ('function' != typeof item.children) {
        if (!item.children && item.name.toLowerCase().includes(query.toLowerCase())) results.push(item);
        else if (item.children) results.push(...searchLeafItems(item.children, query));
    }
    return results;
}
function Toolbox({ onClose, onBack, onItemSelect, onSearch, onItemHover, title, initialItems, loading, fullWidth = false, fullHeight = false, quickActions, renderEmptyState }) {
    const { _ } = (0, external_i18n_index_cjs_namespaceObject.useSafeLingui)();
    const searchPlaceholder = _({
        id: 'toolbox.search',
        message: 'Search'
    });
    const [items, setItems] = (0, external_react_namespaceObject.useState)(initialItems);
    const [search, setSearch] = (0, external_react_namespaceObject.useState)('');
    const [searchLoading, setSearchLoading] = (0, external_react_namespaceObject.useState)(false);
    const [awaitingChildren, setAwaitingChildren] = (0, external_react_namespaceObject.useState)(false);
    const [isSearchingInitialItems, setIsSearchingInitialItems] = (0, external_react_namespaceObject.useState)(true);
    const [searchedItems, setSearchedItems] = (0, external_react_namespaceObject.useState)([]);
    const [currentParentItem, setCurrentParentItem] = (0, external_react_namespaceObject.useState)(null);
    const [isTransitioning, setIsTransitioning] = (0, external_react_namespaceObject.useState)(false);
    const [animationDirection, setAnimationDirection] = (0, external_react_namespaceObject.useState)('forward');
    const navigationStack = (0, index_cjs_namespaceObject.useNavigationStack)();
    const [activeIndex, setActiveIndex] = (0, external_react_namespaceObject.useState)(SEARCH_BAR_INDEX);
    const containerRef = (0, external_react_namespaceObject.useRef)(null);
    const transitionTimeoutRef = (0, external_react_namespaceObject.useRef)(void 0);
    const searchIdRef = (0, external_react_namespaceObject.useRef)(0);
    const initialItemsRef = (0, external_react_namespaceObject.useRef)(initialItems);
    const listRef = (0, external_react_window_namespaceObject.useListRef)(null);
    const listViewRef = (0, external_react_namespaceObject.useRef)(null);
    const searchInputRef = (0, external_react_namespaceObject.useRef)(null);
    const clearButtonRef = (0, external_react_namespaceObject.useRef)(null);
    const lastScrollTopRef = (0, external_react_namespaceObject.useRef)(0);
    const handleListScroll = (0, external_react_namespaceObject.useCallback)((e)=>{
        lastScrollTopRef.current = e.currentTarget.scrollTop;
    }, []);
    const isSearching = (0, external_react_namespaceObject.useMemo)(()=>search.length > 0, [
        search
    ]);
    const wrappedRenderEmptyState = (0, external_react_namespaceObject.useMemo)(()=>renderEmptyState && !isSearching ? ()=>renderEmptyState({
                currentCategory: currentParentItem ?? void 0
            }) : void 0, [
        renderEmptyState,
        isSearching,
        currentParentItem
    ]);
    const displayedItems = (0, external_react_namespaceObject.useMemo)(()=>isSearching && !isSearchingInitialItems ? searchedItems : items, [
        isSearching,
        isSearchingInitialItems,
        searchedItems,
        items
    ]);
    const startTransition = (0, external_react_namespaceObject.useCallback)((direction)=>{
        if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
        setIsTransitioning(true);
        setAnimationDirection(direction);
        transitionTimeoutRef.current = setTimeout(()=>{
            setIsTransitioning(false);
        }, TRANSITION_DURATION);
    }, []);
    const navigateToIndex = (0, external_react_namespaceObject.useCallback)((index)=>{
        setActiveIndex(index);
        searchInputRef.current?.focus();
        if (index !== SEARCH_BAR_INDEX) requestAnimationFrame(()=>{
            listRef.current?.scrollToRow({
                index,
                align: 'auto'
            });
        });
    }, [
        listRef
    ]);
    const navigateToFirstItem = (0, external_react_namespaceObject.useCallback)(()=>{
        const renderedItems = listViewRef.current?.renderedItems ?? [];
        const firstIndex = getFirstSelectableIndex(renderedItems);
        if (firstIndex !== SEARCH_BAR_INDEX) navigateToIndex(firstIndex);
    }, [
        navigateToIndex
    ]);
    const clearSearch = (0, external_react_namespaceObject.useCallback)(()=>{
        setSearch('');
        setSearchedItems([]);
        setSearchLoading(false);
        setIsSearchingInitialItems(true);
        navigateToIndex(SEARCH_BAR_INDEX);
    }, [
        navigateToIndex
    ]);
    const handleSearch = (0, external_react_namespaceObject.useCallback)(async (query)=>{
        if (!query.trim()) {
            setSearchLoading(false);
            setSearchedItems([]);
            setIsSearchingInitialItems(true);
            setSearch('');
            return;
        }
        setSearch(query);
        setActiveIndex(SEARCH_BAR_INDEX);
        searchIdRef.current += 1;
        const currentRequestId = searchIdRef.current;
        setSearchLoading(true);
        const result = onSearch ? await onSearch(query, !navigationStack.canGoBack, {
            currentItems: items,
            category: currentParentItem?.id
        }) : searchLeafItems(items, query);
        if (currentRequestId === searchIdRef.current) {
            setSearchedItems(result);
            setSearchLoading(false);
            setIsSearchingInitialItems(false);
        }
    }, [
        onSearch,
        items,
        navigationStack.canGoBack,
        currentParentItem?.id
    ]);
    const handleBackTransition = (0, external_react_namespaceObject.useCallback)(()=>{
        startTransition('back');
        const previousState = navigationStack.pop();
        if (previousState) {
            setItems(previousState.data.items);
            setCurrentParentItem(previousState.data.parentItem);
        }
        setSearch('');
        setSearchedItems([]);
        setSearchLoading(false);
        setIsSearchingInitialItems(true);
        const restoredIndex = previousState?.data.activeIndex ?? SEARCH_BAR_INDEX;
        const restoredScrollTop = previousState?.data.scrollTop ?? 0;
        setActiveIndex(restoredIndex);
        searchInputRef.current?.focus();
        requestAnimationFrame(()=>{
            const element = listRef.current?.element;
            if (element) element.scrollTop = restoredScrollTop;
            lastScrollTopRef.current = restoredScrollTop;
        });
        onBack?.();
    }, [
        navigationStack,
        onBack,
        startTransition,
        listRef
    ]);
    const handleItemSelect = (0, external_react_namespaceObject.useCallback)(async (item, index)=>{
        if (!item.children) return void onItemSelect(item);
        setAwaitingChildren(true);
        const nestedItems = 'function' == typeof item.children ? await item.children(item.id, item.name) : item.children;
        const savedIndex = isSearching ? SEARCH_BAR_INDEX : index ?? activeIndex;
        const savedScrollTop = isSearching ? 0 : lastScrollTopRef.current;
        navigationStack.push({
            title: currentParentItem?.name || title,
            data: {
                items,
                parentItem: currentParentItem,
                activeIndex: savedIndex,
                scrollTop: savedScrollTop
            }
        });
        setItems(nestedItems);
        setCurrentParentItem(item);
        clearSearch();
        setActiveIndex(SEARCH_BAR_INDEX);
        requestAnimationFrame(()=>{
            const element = listRef.current?.element;
            if (element) element.scrollTop = 0;
            lastScrollTopRef.current = 0;
        });
        startTransition('forward');
        setAwaitingChildren(false);
    }, [
        navigationStack,
        currentParentItem,
        title,
        items,
        activeIndex,
        isSearching,
        clearSearch,
        startTransition,
        onItemSelect,
        listRef
    ]);
    (0, external_react_namespaceObject.useEffect)(()=>()=>{
            if (transitionTimeoutRef.current) clearTimeout(transitionTimeoutRef.current);
        }, []);
    (0, external_react_namespaceObject.useEffect)(()=>{
        if (initialItems === initialItemsRef.current) return;
        const newInitialItems = initialItems;
        initialItemsRef.current = initialItems;
        if (navigationStack.isEmpty) return void setItems(newInitialItems);
        if (currentParentItem) {
            const updatedCurrentParent = findItemById(newInitialItems, currentParentItem.id);
            if (updatedCurrentParent?.children && 'function' != typeof updatedCurrentParent.children) setItems(updatedCurrentParent.children);
            if (updatedCurrentParent) setCurrentParentItem(updatedCurrentParent);
        }
        const updatedStack = navigationStack.stack.map((stackItem)=>{
            if (!stackItem.data.parentItem) return {
                ...stackItem,
                data: {
                    items: newInitialItems,
                    parentItem: null,
                    activeIndex: stackItem.data.activeIndex,
                    scrollTop: stackItem.data.scrollTop
                }
            };
            const updatedParentItem = findItemById(newInitialItems, stackItem.data.parentItem.id);
            let updatedItems = stackItem.data.items;
            if (updatedParentItem?.children && 'function' != typeof updatedParentItem.children) updatedItems = updatedParentItem.children;
            return {
                ...stackItem,
                data: {
                    items: updatedItems,
                    parentItem: updatedParentItem,
                    activeIndex: stackItem.data.activeIndex,
                    scrollTop: stackItem.data.scrollTop
                }
            };
        });
        if (updatedStack.length > 0) {
            navigationStack.clear();
            for (const updatedStackItem of updatedStack)navigationStack.push(updatedStackItem);
        }
    }, [
        initialItems,
        navigationStack,
        currentParentItem
    ]);
    (0, external_react_namespaceObject.useEffect)(()=>{
        if (search) handleSearch(search);
    }, [
        items
    ]);
    const activeDescendantId = (0, external_react_namespaceObject.useMemo)(()=>{
        if (activeIndex < 0) return;
        const renderItem = listViewRef.current?.renderedItems[activeIndex];
        if (renderItem?.type === 'item') return `toolbox-item-${renderItem.item.id}`;
    }, [
        activeIndex
    ]);
    const handleNavigationKeyDown = (0, external_react_namespaceObject.useCallback)((e)=>{
        if (isTransitioning) return;
        const renderedItems = listViewRef.current?.renderedItems ?? [];
        const navigateDown = ()=>{
            if (activeIndex === SEARCH_BAR_INDEX) navigateToFirstItem();
            else {
                const nextIndex = getNextSelectableIndex(renderedItems, activeIndex, 'down');
                if (nextIndex !== SEARCH_BAR_INDEX) navigateToIndex(nextIndex);
                else navigateToFirstItem();
            }
        };
        const navigateUp = ()=>{
            navigateToIndex(getNextSelectableIndex(renderedItems, activeIndex, 'up'));
        };
        switch(e.key){
            case 'ArrowDown':
                e.preventDefault();
                navigateDown();
                break;
            case 'ArrowUp':
                e.preventDefault();
                navigateUp();
                break;
            case ' ':
            case 'Enter':
                {
                    if (activeIndex === SEARCH_BAR_INDEX) return;
                    const renderItem = renderedItems[activeIndex];
                    if (renderItem?.type === 'item') {
                        e.preventDefault();
                        handleItemSelect(renderItem.item);
                    }
                    break;
                }
            case 'ArrowRight':
                {
                    const renderItem = renderedItems[activeIndex];
                    if (renderItem?.type === 'item' && renderItem.item.children) {
                        e.preventDefault();
                        handleItemSelect(renderItem.item);
                    }
                    break;
                }
            case 'ArrowLeft':
                if (!navigationStack.canGoBack || activeIndex === SEARCH_BAR_INDEX && search.length > 0) return;
                e.preventDefault();
                handleBackTransition();
                break;
            case 'Tab':
                if (activeIndex === SEARCH_BAR_INDEX && search.length > 0 && !e.shiftKey) break;
                e.preventDefault();
                if (activeIndex === SEARCH_BAR_INDEX && e.shiftKey) break;
                if (e.shiftKey) {
                    navigateUp();
                    const nextUp = getNextSelectableIndex(renderedItems, activeIndex, 'up');
                    if (nextUp === SEARCH_BAR_INDEX && search.length > 0) clearButtonRef.current?.focus();
                } else navigateDown();
                break;
            case 'Home':
                if (activeIndex === SEARCH_BAR_INDEX) break;
                e.preventDefault();
                navigateToFirstItem();
                break;
            case 'End':
                {
                    if (activeIndex === SEARCH_BAR_INDEX) break;
                    e.preventDefault();
                    const lastIndex = getLastSelectableIndex(renderedItems);
                    if (lastIndex !== SEARCH_BAR_INDEX) navigateToIndex(lastIndex);
                    break;
                }
        }
    }, [
        search,
        isTransitioning,
        activeIndex,
        navigationStack.canGoBack,
        navigateToIndex,
        navigateToFirstItem,
        handleItemSelect,
        handleBackTransition
    ]);
    const handleClose = (0, external_react_namespaceObject.useCallback)(()=>{
        navigationStack.clear();
        onClose();
    }, [
        navigationStack,
        onClose
    ]);
    (0, external_react_namespaceObject.useEffect)(()=>{
        const handleKeyDown = (e)=>{
            if ('Escape' === e.key) if (isSearching) {
                searchIdRef.current += 1;
                startTransition('back');
                clearSearch();
            } else if (navigationStack.canGoBack) handleBackTransition();
            else handleClose();
        };
        const handleClickOutside = (e)=>{
            if (containerRef.current && !containerRef.current.contains(e.target)) handleClose();
        };
        document.addEventListener('keydown', handleKeyDown);
        document.addEventListener('mousedown', handleClickOutside);
        return ()=>{
            document.removeEventListener('keydown', handleKeyDown);
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, [
        isSearching,
        navigationStack.canGoBack,
        handleClose,
        clearSearch,
        startTransition,
        handleBackTransition
    ]);
    return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)("div", {
        ref: containerRef,
        "data-testid": "toolbox-container",
        children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(external_layouts_index_cjs_namespaceObject.Column, {
            px: external_constants_cjs_namespaceObject.TOOLBOX_PADDING_X,
            py: external_constants_cjs_namespaceObject.TOOLBOX_PADDING_Y,
            gap: external_constants_cjs_namespaceObject.TOOLBOX_GAP,
            w: fullWidth ? '100%' : external_constants_cjs_namespaceObject.TOOLBOX_WIDTH,
            h: fullHeight ? '100%' : external_constants_cjs_namespaceObject.TOOLBOX_HEIGHT,
            children: [
                quickActions && quickActions.length > 0 && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_QuickActionsRow_cjs_namespaceObject.QuickActionsRow, {
                    actions: quickActions
                }),
                /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Header_cjs_namespaceObject.Header, {
                    title: currentParentItem?.name || title,
                    onBack: handleBackTransition,
                    showBackButton: navigationStack.canGoBack
                }),
                /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_SearchBox_cjs_namespaceObject.SearchBox, {
                    value: search,
                    onChange: handleSearch,
                    clear: clearSearch,
                    placeholder: searchPlaceholder,
                    inputRef: searchInputRef,
                    clearButtonRef: clearButtonRef,
                    onNavigationKeyDown: handleNavigationKeyDown,
                    navigateToFirstItem: navigateToFirstItem,
                    activeDescendantId: activeDescendantId
                }),
                /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContainer, {
                    children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_Toolbox_styles_cjs_namespaceObject.AnimatedContent, {
                        entering: isTransitioning,
                        direction: animationDirection,
                        children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_ListView_cjs_namespaceObject.ListView, {
                            ref: listViewRef,
                            isLoading: awaitingChildren || searchLoading || loading,
                            items: displayedItems,
                            activeIndex: activeIndex,
                            listRef: listRef,
                            emptyStateMessage: isSearching ? 'No matching nodes found' : 'No nodes found',
                            renderEmptyState: wrappedRenderEmptyState,
                            onItemClick: handleItemSelect,
                            onItemHover: onItemHover,
                            onScroll: handleListScroll,
                            enableSections: !isSearching,
                            loadingSkeleton: isSearching ? void 0 : currentParentItem?.childrenLoading
                        })
                    })
                })
            ]
        })
    });
}
exports.Toolbox = __webpack_exports__.Toolbox;
for(var __rspack_i in __webpack_exports__)if (-1 === [
    "Toolbox"
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
Object.defineProperty(exports, '__esModule', {
    value: true
});
