import { jsx as _jsx } from "@emotion/react/jsx-runtime";
import { useCallback, useMemo, useEffect, useRef, } from 'react';
import { Tree as AntdTree } from 'antd';
import { useTreeKeys } from '../../hooks';
import { isScrolledIntoView } from '../../../utils/is-scrolled-into-view';
import { getIdByPath } from '../../../utils/get-id-by-path';
import { filterNestedPaths } from '../../../utils/filter-nested-paths';
import { arraysEqual } from '../../../utils/arrays-equal';
import { useTreeData } from './hooks/use-tree-data';
import { ListWrapper } from './list-wrapper';
import { TreeCSS } from './tree.style';
export const TreeNodeTitle = ({ title, selected, getContainer, }) => {
    const nodeRef = useRef(null);
    useEffect(() => {
        if (!nodeRef.current) {
            return;
        }
        if (selected && !isScrolledIntoView(nodeRef.current, getContainer())) {
            nodeRef.current.scrollIntoView({ block: 'center' });
        }
    }, [selected]);
    return _jsx("span", { ref: nodeRef, children: title });
};
export const Tree = ({ className, treeData, inspectedKey, selectedPaths, persistentStorageKey, draggable, onDrop, childrenFieldMap, onSelect, onInspect, onClickOutside, showIcon = true, }) => {
    const containerRef = useRef(null);
    const { expandedKeys, setExpandedKeys } = useTreeKeys(treeData, inspectedKey, persistentStorageKey ? `${persistentStorageKey}.expandedKeys` : undefined);
    const { treeData: parsedTreeData } = useTreeData(treeData);
    const selectedKeys = useMemo(() => selectedPaths === null || selectedPaths === void 0 ? void 0 : selectedPaths.map(getIdByPath), [selectedPaths]);
    const handleExpand = useCallback((keys) => {
        setExpandedKeys(keys);
    }, []);
    const handleSelect = useCallback((keys, info) => {
        const { selectedNodes, node } = info;
        onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedNodes.map((selectedNode) => selectedNode.path.slice(0)));
        onInspect === null || onInspect === void 0 ? void 0 : onInspect(selectedNodes.length ? node.path.slice(0) : undefined);
    }, [onSelect, onInspect]);
    const handleDrop = useCallback((info) => {
        if (!onDrop || !childrenFieldMap) {
            return;
        }
        const { node, dragNode } = info;
        const isWithinSelection = selectedPaths === null || selectedPaths === void 0 ? void 0 : selectedPaths.some((path) => getIdByPath(path) === dragNode.key);
        const paths = isWithinSelection ? selectedPaths : [dragNode.path];
        const sourcePaths = filterNestedPaths(paths);
        const childrenField = childrenFieldMap[node.path.at(-2)];
        if (!childrenField) {
            return;
        }
        const destinationPath = node.path.concat(childrenField);
        if (sourcePaths.some((path) => arraysEqual(path.slice(0, -1), destinationPath))) {
            return;
        }
        if (sourcePaths.some((path) => arraysEqual(path, node.path))) {
            return;
        }
        onDrop(sourcePaths, destinationPath);
    }, [selectedPaths, onDrop, childrenFieldMap]);
    const getContainer = useCallback(() => containerRef.current, []);
    return (_jsx(ListWrapper, { ref: containerRef, onClickOutside: onClickOutside, children: _jsx(AntdTree.DirectoryTree, { css: TreeCSS, className: className, expandedKeys: expandedKeys, selectedKeys: selectedKeys, onSelect: handleSelect, onExpand: handleExpand, onDrop: handleDrop, treeData: parsedTreeData, expandAction: "doubleClick", draggable: draggable ? { icon: false } : undefined, multiple: true, titleRender: (nodeData) => {
                var _a;
                return (_jsx(TreeNodeTitle, Object.assign({}, nodeData, { selected: (_a = selectedKeys === null || selectedKeys === void 0 ? void 0 : selectedKeys.includes(String(nodeData.key))) !== null && _a !== void 0 ? _a : false, getContainer: getContainer })));
            }, showIcon: showIcon }) }));
};
