import { hasProp } from '../../utils';
const helpers = {
    isItem(item) {
        return hasProp(item, 'primary');
    },
    getItem(items, id) {
        let found;
        items.some(item => {
            if (this.isItem(item) && item.id === id) {
                found = item;
                return true;
            }
            if (item.items) {
                found = this.getItem(item.items, id);
                return !!found;
            }
            return false;
        });
        return found;
    },
    getPath(items, id) {
        let path = [];
        items.some(item => {
            if (item.id === id) {
                path = [item];
                return true;
            }
            if (item.items) {
                const innerPath = this.getPath(item.items, id);
                if (innerPath.length)
                    path = innerPath.concat(item);
                return !!path.length;
            }
            return false;
        });
        return path;
    },
    setItem(items, id, newItem) {
        return items.map(item => {
            if (item.id === id)
                return { ...newItem };
            if (item.items) {
                return {
                    ...item,
                    items: this.setItem(item.items, id, newItem)
                };
            }
            return item;
        });
    },
    mapItem(items, id, fn) {
        return items.map((item, index, array) => {
            let newItem = item;
            if (item.items) {
                newItem = {
                    ...newItem,
                    items: this.mapItem(item.items, id, fn)
                };
            }
            if (this.isItem(newItem) && item.id === id) {
                newItem = fn(newItem, index, array);
            }
            return newItem;
        });
    },
    mapTree(items, fn) {
        return items.map((item, index, array) => {
            let newItem = item;
            if (item.items) {
                newItem = {
                    ...newItem,
                    items: this.mapTree(item.items, fn)
                };
            }
            return this.isItem(newItem) ? fn(newItem, index, array) : newItem;
        });
    },
    flatten(items, ancestors = [], options = { parentFirst: false }) {
        let allItems = [];
        let leafItems = [];
        items.forEach(item => {
            if (this.isItem(item)) {
                allItems.push(ancestors.length > 0 ? { ...item, ancestors } : item);
            }
            if (item.items) {
                const children = this.flatten(item.items, [...ancestors, item], options);
                if (options.parentFirst) {
                    leafItems = [...leafItems, ...children];
                }
                else {
                    allItems = [...allItems, ...children];
                }
            }
        });
        return options.parentFirst ? [...allItems, ...leafItems] : allItems;
    },
    toggleSelected(items, id, mode, bool) {
        return this.mapTree(items, item => {
            if (this.isItem(item)) {
                if (item.id === id) {
                    return {
                        ...item,
                        selected: bool !== undefined ? bool : !item.selected
                    };
                }
                if (mode === 'single-select') {
                    return {
                        ...item,
                        selected: false
                    };
                }
            }
            return item;
        });
    },
    selectItem(items, id, mode) {
        return this.toggleSelected(items, id, mode, true);
    },
    deselectItem(items, id, mode) {
        return this.toggleSelected(items, id, mode, false);
    },
    getSelected(items) {
        return items.reduce((selections, item) => {
            if (this.isItem(item) && item.selected) {
                selections = [...selections, item];
            }
            if (item.items) {
                selections = [...selections, ...this.getSelected(item.items)];
            }
            return selections;
        }, []);
    },
    prependTo(items, newItems, id) {
        if (id) {
            return this.mapItem(items, id, item => ({
                ...item,
                items: [...newItems, ...(item.items ?? [])]
            }));
        }
        return [...newItems, ...items];
    },
    appendTo(items, newItems, id) {
        if (id) {
            return this.mapItem(items, id, item => ({
                ...item,
                items: [...(item.items ?? []), ...newItems]
            }));
        }
        return [...items, ...newItems];
    },
    getNextItem(items, itemId) {
        if (!itemId)
            return items[0];
        let nextItem;
        this.mapItem(items, itemId, (item, index, list) => {
            nextItem = list[index + 1];
            return item;
        });
        return nextItem;
    },
    getPrevItem(items, itemId) {
        if (!itemId)
            return items[0];
        let prevItem;
        this.mapItem(items, itemId, (item, index, list) => {
            prevItem = list[index - 1];
            return item;
        });
        return prevItem;
    },
    getParentItem(items, itemId) {
        if (!itemId)
            return undefined;
        const [, parentItem] = this.getPath(items, itemId);
        return parentItem;
    }
};
export default helpers;
//# sourceMappingURL=helpers.js.map