import { jsx, jsxs } from "react/jsx-runtime";
import react, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { TableOutlined } from "@ant-design/icons";
import { Divider, Empty, Input, Spin } from "antd";
import { useTranslation } from "react-i18next";
import { SchemaInitializerItem, SchemaInitializerMenu, useGetSchemaInitializerMenuItems, useSchemaInitializer } from "../../application/index.mjs";
import { Icon } from "../../icon/index.mjs";
import { useCompile } from "../../schema-component/index.mjs";
import { useSchemaTemplateManager } from "../../schema-templates/index.mjs";
import { useCollectionDataSourceItems } from "../utils.mjs";
const MENU_ITEM_HEIGHT = 40;
const STEP = 15;
const SearchCollections = (param)=>{
    let { value: outValue, onChange } = param;
    const { t } = useTranslation();
    const [value, setValue] = useState(outValue);
    const inputRef = react.useRef(null);
    useEffect(()=>{
        setValue(outValue);
    }, [
        outValue
    ]);
    useEffect(()=>{
        inputRef.current.input.focus();
        const observer = new IntersectionObserver((entries)=>{
            if (entries[0].isIntersecting) inputRef.current.input.focus();
        });
        observer.observe(inputRef.current.input);
        return ()=>{
            observer.disconnect();
        };
    }, []);
    return /*#__PURE__*/ jsxs("div", {
        style: {
            width: 210
        },
        onClick: (e)=>e.stopPropagation(),
        children: [
            /*#__PURE__*/ jsx(Input, {
                ref: inputRef,
                allowClear: true,
                style: {
                    padding: '0 4px 6px',
                    boxShadow: 'none'
                },
                bordered: false,
                placeholder: t('Search and select collection'),
                value: value,
                onClick: (e)=>{
                    e.stopPropagation();
                },
                onChange: (e)=>{
                    onChange(e.target.value);
                    setValue(e.target.value);
                }
            }),
            /*#__PURE__*/ jsx(Divider, {
                style: {
                    margin: 0
                }
            })
        ]
    });
};
const LoadingItem = (param)=>{
    let { loadMore, maxHeight } = param;
    const spinRef = useRef(null);
    useEffect(()=>{
        const el = spinRef.current;
        if (!el) return;
        let container = el.parentElement;
        while(container && 'UL' !== container.tagName)container = container.parentElement;
        const checkLoadMore = function() {
            if (!container) return;
            if (Math.abs(container.scrollHeight - container.scrollTop - container.clientHeight) <= MENU_ITEM_HEIGHT) loadMore();
        };
        if (container) {
            container.style.height = "".concat(maxHeight - MENU_ITEM_HEIGHT, "px");
            container.style.maxHeight = 'inherit';
            container.style.overflowY = 'scroll';
            container.addEventListener('scroll', checkLoadMore);
        }
        return ()=>{
            if (container) {
                container.removeEventListener('scroll', checkLoadMore);
                delete container.style.height;
            }
        };
    }, [
        loadMore,
        maxHeight
    ]);
    return /*#__PURE__*/ jsx("div", {
        ref: spinRef,
        onClick: (e)=>e.stopPropagation(),
        children: /*#__PURE__*/ jsx(Spin, {
            size: "small",
            style: {
                width: '100%'
            }
        })
    });
};
function useMenuSearch(param) {
    let { data, openKeys, showType, hideSearch } = param;
    const [searchValue, setSearchValue] = useState('');
    const [count, setCount] = useState(STEP);
    const isMuliSource = useMemo(()=>data.length > 1, [
        data
    ]);
    const openKey = useMemo(()=>isMuliSource ? null == openKeys ? void 0 : openKeys[1] : (null == openKeys ? void 0 : openKeys.length) > 0, [
        openKeys
    ]);
    useEffect(()=>{
        if (!openKey) setSearchValue('');
    }, [
        openKey
    ]);
    const currentItems = useMemo(()=>{
        var _data_;
        if (isMuliSource) {
            var _data_find;
            if (!openKey) return [];
            return (null == (_data_find = data.find((item)=>(item.key || item.name) === openKey)) ? void 0 : _data_find.children) || [];
        }
        return (null == (_data_ = data[0]) ? void 0 : _data_.children) || [];
    }, [
        data,
        isMuliSource,
        openKey
    ]);
    const searchedItems = useMemo(()=>{
        if (!searchValue) return currentItems;
        const lowerSearchValue = searchValue.toLocaleLowerCase();
        return currentItems.filter((item)=>(item.label || item.title) && String(item.label || item.title).toLocaleLowerCase().includes(lowerSearchValue));
    }, [
        searchValue,
        currentItems
    ]);
    const shouldLoadMore = useMemo(()=>searchedItems.length > count, [
        count,
        searchedItems
    ]);
    const limitedSearchedItems = useMemo(()=>searchedItems.slice(0, count), [
        searchedItems,
        count
    ]);
    const resultItems = useMemo(()=>{
        const res = [];
        if (!hideSearch) res.push(Object.assign({
            key: 'search',
            label: /*#__PURE__*/ jsx(SearchCollections, {
                value: searchValue,
                onChange: (val)=>{
                    setCount(STEP);
                    setSearchValue(val);
                }
            }),
            onClick (param) {
                let { domEvent } = param;
                domEvent.stopPropagation();
            }
        }, showType ? {
            isMenuType: true
        } : {}));
        if (limitedSearchedItems.length > 0) {
            res.push(...limitedSearchedItems);
            if (shouldLoadMore) res.push(Object.assign({
                key: 'load-more',
                label: /*#__PURE__*/ jsx(LoadingItem, {
                    maxHeight: STEP * MENU_ITEM_HEIGHT,
                    loadMore: ()=>{
                        setCount((count)=>count + STEP);
                    }
                })
            }, showType ? {
                isMenuType: true
            } : {}));
        } else res.push(Object.assign({
            key: 'empty',
            style: {
                height: 150
            },
            label: /*#__PURE__*/ jsx("div", {
                onClick: (e)=>e.stopPropagation(),
                children: /*#__PURE__*/ jsx(Empty, {
                    image: Empty.PRESENTED_IMAGE_SIMPLE
                })
            })
        }, showType ? {
            isMenuType: true
        } : {}));
        return res;
    }, [
        hideSearch,
        limitedSearchedItems,
        searchValue,
        shouldLoadMore,
        showType
    ]);
    const res = useMemo(()=>{
        if (!isMuliSource) return resultItems;
        return data.map((item)=>{
            if (openKey && item.key === openKey) return {
                ...item,
                children: resultItems
            };
            return {
                ...item,
                children: []
            };
        });
    }, [
        data,
        isMuliSource,
        openKey,
        resultItems
    ]);
    return res;
}
const DataBlockInitializer = (props)=>{
    var _childItems__children;
    const { templateWrap, onCreateBlockSchema, componentType, icon = TableOutlined, name, title, filter, onlyCurrentDataSource, hideSearch, showAssociationFields, hideChildrenIfSingleCollection, filterDataSource, items: itemsFromProps, fromOthersInPopup, hideOtherRecordsInPopup } = props;
    const { insert, setVisible } = useSchemaInitializer();
    const compile = useCompile();
    const { getTemplateSchemaByMode } = useSchemaTemplateManager();
    const onClick = useCallback(async (param)=>{
        let { item } = param;
        if (item.template) {
            const s = await getTemplateSchemaByMode(item);
            templateWrap ? insert(templateWrap(s, {
                item,
                fromOthersInPopup
            })) : insert(s);
        } else if (onCreateBlockSchema) onCreateBlockSchema({
            item,
            fromOthersInPopup
        });
        setVisible(false);
    }, [
        fromOthersInPopup,
        getTemplateSchemaByMode,
        insert,
        onCreateBlockSchema,
        setVisible,
        templateWrap
    ]);
    const items = itemsFromProps || useCollectionDataSourceItems({
        componentName: componentType,
        filter,
        filterDataSource,
        onlyCurrentDataSource,
        showAssociationFields,
        dataBlockInitializerProps: props,
        hideOtherRecordsInPopup
    });
    const getMenuItems = useGetSchemaInitializerMenuItems(onClick);
    const childItems = useMemo(()=>getMenuItems(items, name), [
        getMenuItems,
        items,
        name
    ]);
    const [openMenuKeys, setOpenMenuKeys] = useState([]);
    const searchedChildren = useMenuSearch({
        data: childItems,
        openKeys: openMenuKeys,
        hideSearch
    });
    const compiledMenuItems = useMemo(()=>{
        let children = searchedChildren.filter((item)=>'search' !== item.key && 'empty' !== item.key);
        children = hideChildrenIfSingleCollection && 1 === children.length ? children[0].children : searchedChildren;
        return [
            {
                key: name,
                label: compile(title),
                icon: 'string' == typeof icon ? /*#__PURE__*/ jsx(Icon, {
                    type: icon
                }) : icon,
                onClick: (info)=>{
                    if (info.key !== name) return;
                    onClick({
                        ...info,
                        item: props
                    });
                },
                children
            }
        ];
    }, [
        searchedChildren,
        hideChildrenIfSingleCollection,
        name,
        compile,
        title,
        icon,
        onClick,
        props
    ]);
    if (childItems.length > 1 || 1 === childItems.length && (null == (_childItems__children = childItems[0].children) ? void 0 : _childItems__children.length) > 0) return /*#__PURE__*/ jsx(SchemaInitializerMenu, {
        onOpenChange: (keys)=>{
            setOpenMenuKeys(keys);
        },
        items: compiledMenuItems
    });
    return /*#__PURE__*/ jsx(SchemaInitializerItem, {
        ...props,
        onClick: onClick
    });
};
export { DataBlockInitializer, SearchCollections, useMenuSearch };
