import { jsx, jsxs } from "react/jsx-runtime";
import { createContext, useContext, useEffect, useMemo, useRef, useState } from "react";
import { FieldContext, RecursionField, SchemaContext, SchemaExpressionScopeContext, observer, uid, useField, useFieldSchema } from "@tachybase/schema";
import { error } from "@tego/client";
import { PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
import { Button, Menu, Popover } from "antd";
import { createPortal } from "react-dom";
import { DndContext, SortableItem, createDesignable, useDesignable, useDesigner } from "../../index.mjs";
import { Icon, css, useAPIClient, useSchemaInitializerRender, useToken, useTranslation } from "../../../index.mjs";
import { useCollectMenuItems, useMenuItem } from "../../../hooks/useMenuItem.mjs";
import { DragHandleMenu } from "../../common/sortable-item/DragHandleMenu.mjs";
import { useProps } from "../../hooks/useProps.mjs";
import { AdminMenu } from "./AdminMenu.mjs";
import { useMenuTranslation } from "./locale.mjs";
import { MenuDesigner } from "./Menu.Designer.mjs";
import { useStyles } from "./Menu.styles.mjs";
import { MenuSearchAdd } from "./MenuSearchAdd.mjs";
import { getNewSideMenuSchema } from "./tools.mjs";
import { findKeysByUid, findMenuItem } from "./util.mjs";
function _tagged_template_literal(strings, raw) {
    if (!raw) raw = strings.slice(0);
    return Object.freeze(Object.defineProperties(strings, {
        raw: {
            value: Object.freeze(raw)
        }
    }));
}
function _templateObject() {
    const data = _tagged_template_literal([
        "\n          .iconButton {\n            border: 0;\n            height: var(--tb-header-height);\n            width: 46px;\n            border-radius: 0;\n            background: none;\n            color: rgba(255, 255, 255, 0.65);\n            &:hover {\n              background: rgba(255, 255, 255, 0.1) !important;\n            }\n          }\n        "
    ]);
    _templateObject = function() {
        return data;
    };
    return data;
}
const HeaderMenu = (param)=>{
    let { others, schema, mode, onSelect, setLoading, setDefaultSelectedKeys, designable, render, children } = param;
    const { Component, getMenuItems } = useMenuItem();
    const { token } = useToken();
    const { styles } = useStyles();
    const [items, setItems] = useState([]);
    const result = getMenuItems(()=>children);
    useEffect(()=>{
        setItems(getItem());
    }, [
        children,
        designable,
        getMenuItems
    ]);
    const getItem = ()=>{
        const designerBtn = {
            key: 'x-designer-button',
            label: render({
                'data-testid': 'schema-initializer-Menu-header',
                style: {
                    background: 'none',
                    height: '100%'
                }
            }),
            notdelete: true,
            disabled: true
        };
        if (designable) result.push(designerBtn);
        return result;
    };
    const onClick = (info)=>{
        var _schema_properties;
        const s = null == (_schema_properties = schema.properties) ? void 0 : _schema_properties[info.key];
        if (!s) return;
        if ('mix' === mode) if ('Menu.SubMenu' !== s['x-component']) null == onSelect || onSelect({
            item: {
                props: info
            }
        });
        else {
            const menuItemSchema = findMenuItem(s);
            if (!menuItemSchema) return null == onSelect ? void 0 : onSelect({
                item: {
                    props: info
                }
            });
            setLoading(true);
            const keys = findKeysByUid(schema, menuItemSchema['x-uid']);
            setDefaultSelectedKeys(keys);
            setTimeout(()=>{
                setLoading(false);
            }, 100);
            null == onSelect || onSelect({
                key: menuItemSchema.name,
                item: {
                    props: {
                        schema: menuItemSchema
                    }
                }
            });
        }
        else null == onSelect || onSelect({
            item: {
                props: info
            }
        });
    };
    return /*#__PURE__*/ jsxs("div", {
        className: styles.headerMenuClass,
        children: [
            /*#__PURE__*/ jsx("div", {
                style: {
                    flex: 1
                }
            }),
            /*#__PURE__*/ jsxs("div", {
                className: css(_templateObject()),
                children: [
                    /*#__PURE__*/ jsx(Popover, {
                        placement: "bottomRight",
                        arrow: false,
                        overlayInnerStyle: {
                            padding: 0
                        },
                        content: /*#__PURE__*/ jsx(AdminMenu, {
                            items: items,
                            onClick: onClick
                        }),
                        children: /*#__PURE__*/ jsx(Button, {
                            className: "iconButton",
                            icon: /*#__PURE__*/ jsx(Icon, {
                                type: "apps",
                                style: {
                                    color: token.colorTextHeaderMenu
                                }
                            })
                        })
                    }),
                    /*#__PURE__*/ jsx(Component, {})
                ]
            })
        ]
    });
};
const SideMenu = (param)=>{
    let { loading, mode, sideMenuSchema, sideMenuRef, defaultOpenKeys, defaultSelectedKeys, onSelect, render, t, api, refresh, designable } = param;
    var _sideMenuRef_current;
    const { Component, getMenuItems } = useMenuItem();
    const { styles } = useStyles();
    const sideMenuSchemaRef = useRef(sideMenuSchema);
    sideMenuSchemaRef.current = sideMenuSchema;
    const [searchMenuTitle, setSearchMenuTitle] = useState('');
    const items = useMemo(()=>{
        let newSideMenuSchema = sideMenuSchema;
        if (searchMenuTitle) newSideMenuSchema = getNewSideMenuSchema(sideMenuSchema, searchMenuTitle);
        const result = getMenuItems(()=>/*#__PURE__*/ jsx(RecursionField, {
                schema: newSideMenuSchema,
                onlyRenderProperties: true
            }, uid()));
        {
            const dn = createDesignable({
                t,
                api,
                refresh,
                current: sideMenuSchemaRef.current
            });
            dn.loadAPIClientEvents();
            const searchMenu = {
                key: 'x-menu-search',
                disabled: true,
                label: /*#__PURE__*/ jsx(MenuSearchAdd, {
                    designable: designable,
                    setSearchMenuTitle: setSearchMenuTitle,
                    dn: dn
                }),
                order: -10,
                notdelete: true
            };
            result.push(searchMenu);
        }
        return result;
    }, [
        getMenuItems,
        designable,
        sideMenuSchema,
        render,
        t,
        api,
        refresh,
        searchMenuTitle
    ]);
    if (loading) return null;
    return 'mix' === mode && (null == sideMenuSchema ? void 0 : sideMenuSchema['x-component']) === 'Menu.SubMenu' && (null == sideMenuRef ? void 0 : null == (_sideMenuRef_current = sideMenuRef.current) ? void 0 : _sideMenuRef_current.firstChild) && /*#__PURE__*/ createPortal(/*#__PURE__*/ jsxs(MenuModeContext.Provider, {
        value: 'inline',
        children: [
            /*#__PURE__*/ jsx(Component, {}),
            /*#__PURE__*/ jsx(Menu, {
                mode: 'inline',
                defaultOpenKeys: defaultOpenKeys,
                defaultSelectedKeys: defaultSelectedKeys,
                onSelect: (info)=>{
                    null == onSelect || onSelect(info);
                },
                className: styles.sideMenuClass,
                items: items,
                expandIcon: null
            })
        ]
    }), sideMenuRef.current.firstChild);
};
const MenuModeContext = /*#__PURE__*/ createContext(null);
MenuModeContext.displayName = 'MenuModeContext';
const useSideMenuRef = ()=>{
    var _schema_xcomponentprops;
    const schema = useFieldSchema();
    const scope = useContext(SchemaExpressionScopeContext);
    const scopeKey = null == schema ? void 0 : null == (_schema_xcomponentprops = schema['x-component-props']) ? void 0 : _schema_xcomponentprops['sideMenuRefScopeKey'];
    if (!scopeKey) return;
    return scope[scopeKey];
};
const MenuItemDesignerContext = /*#__PURE__*/ createContext(null);
MenuItemDesignerContext.displayName = 'MenuItemDesignerContext';
const Menu_Menu = observer((props)=>{
    const { onSelect, mode, selectedUid, defaultSelectedUid, sideMenuRefScopeKey, defaultSelectedKeys: dSelectedKeys, defaultOpenKeys: dOpenKeys, children, ...others } = useProps(props);
    const { t } = useTranslation();
    const { refresh } = useDesignable();
    const api = useAPIClient();
    const Designer = useDesigner();
    const schema = useFieldSchema();
    const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']);
    const sideMenuRef = useSideMenuRef();
    const [selectedKeys, setSelectedKeys] = useState();
    const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(()=>{
        if (dSelectedKeys) return dSelectedKeys;
        if (defaultSelectedUid) return findKeysByUid(schema, defaultSelectedUid);
        return [];
    });
    const [loading, setLoading] = useState(false);
    const [defaultOpenKeys, setDefaultOpenKeys] = useState(()=>{
        if ([
            'inline',
            'mix'
        ].includes(mode)) return dOpenKeys || defaultSelectedKeys;
        return dOpenKeys;
    });
    const sensors = useSensors(useSensor(PointerSensor, {
        activationConstraint: {
            distance: 5
        }
    }));
    const sideMenuSchema = useMemo(()=>{
        let key;
        if (selectedUid) {
            const keys = findKeysByUid(schema, selectedUid);
            key = (null == keys ? void 0 : keys[0]) || null;
        } else key = (null == defaultSelectedKeys ? void 0 : defaultSelectedKeys[0]) || null;
        if ('mix' === mode && key) {
            var _schema_properties;
            const s = null == (_schema_properties = schema.properties) ? void 0 : _schema_properties[key];
            if ((null == s ? void 0 : s['x-component']) === 'Menu.SubMenu') return s;
        }
        return null;
    }, [
        defaultSelectedKeys,
        mode,
        schema,
        selectedUid
    ]);
    useEffect(()=>{
        if (!selectedUid) return void setSelectedKeys(void 0);
        const keys = findKeysByUid(schema, selectedUid);
        setSelectedKeys(keys);
        if ([
            'inline',
            'mix'
        ].includes(mode)) setDefaultOpenKeys(dOpenKeys || keys);
    }, [
        selectedUid
    ]);
    useEffect(()=>{
        if ([
            'inline',
            'mix'
        ].includes(mode)) setDefaultOpenKeys(defaultSelectedKeys);
    }, [
        defaultSelectedKeys
    ]);
    const { designable } = useDesignable();
    return /*#__PURE__*/ jsx(DndContext, {
        sensors: sensors,
        children: /*#__PURE__*/ jsx(MenuItemDesignerContext.Provider, {
            value: Designer,
            children: /*#__PURE__*/ jsxs(MenuModeContext.Provider, {
                value: mode,
                children: [
                    /*#__PURE__*/ jsx(HeaderMenu, {
                        others: others,
                        schema: schema,
                        mode: mode,
                        onSelect: onSelect,
                        setLoading: setLoading,
                        setDefaultSelectedKeys: setDefaultSelectedKeys,
                        designable: designable,
                        render: render,
                        children: children
                    }),
                    /*#__PURE__*/ jsx(SideMenu, {
                        loading: loading,
                        mode: mode,
                        sideMenuSchema: sideMenuSchema,
                        sideMenuRef: sideMenuRef,
                        defaultOpenKeys: defaultOpenKeys,
                        defaultSelectedKeys: defaultSelectedKeys,
                        onSelect: onSelect,
                        render: render,
                        t: t,
                        api: api,
                        refresh: refresh,
                        designable: designable
                    })
                ]
            })
        })
    });
}, {
    displayName: 'Menu'
});
Menu_Menu.Item = observer((props)=>{
    const { t } = useMenuTranslation();
    const { pushMenuItem } = useCollectMenuItems();
    const { icon, children, ...others } = props;
    const schema = useFieldSchema();
    const { styles } = useStyles();
    const field = useField();
    const Designer = useContext(MenuItemDesignerContext);
    const item = useMemo(()=>({
            ...others,
            className: styles.menuItemClass,
            key: schema.name,
            eventKey: schema.name,
            schema,
            menu: {
                icon,
                field,
                Designer,
                schema,
                styles
            },
            label: /*#__PURE__*/ jsx(SchemaContext.Provider, {
                value: schema,
                children: /*#__PURE__*/ jsx(FieldContext.Provider, {
                    value: field,
                    children: /*#__PURE__*/ jsx(SortableItem, {
                        role: "button",
                        "aria-label": t(field.title),
                        className: styles.designerCss,
                        removeParentsIfNoChildren: false,
                        overStyle: {
                            background: 'transparent'
                        },
                        children: /*#__PURE__*/ jsxs(DragHandleMenu, {
                            children: [
                                /*#__PURE__*/ jsxs("span", {
                                    className: 'menuitem-title-wrapper',
                                    children: [
                                        /*#__PURE__*/ jsx(Icon, {
                                            type: icon
                                        }),
                                        /*#__PURE__*/ jsx("span", {
                                            className: 'menuitem-title',
                                            children: t(field.title)
                                        })
                                    ]
                                }),
                                /*#__PURE__*/ jsx(Designer, {})
                            ]
                        })
                    })
                })
            })
        }), [
        field.title,
        icon,
        schema,
        Designer
    ]);
    if (!pushMenuItem) {
        error('Menu.Item must be wrapped by GetMenuItemsContext.Provider');
        return null;
    }
    pushMenuItem(item);
    return null;
}, {
    displayName: 'Menu.Item'
});
Menu_Menu.URL = observer((props)=>{
    const { t } = useMenuTranslation();
    const { pushMenuItem } = useCollectMenuItems();
    const { icon, children, ...others } = props;
    const schema = useFieldSchema();
    const field = useField();
    const Designer = useContext(MenuItemDesignerContext);
    const { styles } = useStyles();
    if (!pushMenuItem) {
        error('Menu.URL must be wrapped by GetMenuItemsContext.Provider');
        return null;
    }
    const item = useMemo(()=>({
            ...others,
            className: styles.menuItemClass,
            key: schema.name,
            eventKey: schema.name,
            schema,
            onClick: ()=>{
                window.open(props.href, '_blank');
            },
            menu: {
                icon,
                field,
                Designer,
                schema,
                styles
            },
            label: /*#__PURE__*/ jsx(SchemaContext.Provider, {
                value: schema,
                children: /*#__PURE__*/ jsx(FieldContext.Provider, {
                    value: field,
                    children: /*#__PURE__*/ jsx(SortableItem, {
                        className: styles.designerCss,
                        removeParentsIfNoChildren: false,
                        "aria-label": t(field.title),
                        overStyle: {
                            background: 'transparent'
                        },
                        children: /*#__PURE__*/ jsxs(DragHandleMenu, {
                            children: [
                                /*#__PURE__*/ jsxs("span", {
                                    className: 'menuitem-title-wrapper',
                                    children: [
                                        /*#__PURE__*/ jsx(Icon, {
                                            type: icon
                                        }),
                                        /*#__PURE__*/ jsx("span", {
                                            style: {
                                                overflow: 'hidden',
                                                textOverflow: 'ellipsis',
                                                display: 'inline-block',
                                                width: '100%',
                                                verticalAlign: 'middle'
                                            },
                                            children: t(field.title)
                                        })
                                    ]
                                }),
                                /*#__PURE__*/ jsx(Designer, {})
                            ]
                        })
                    })
                })
            })
        }), [
        field.title,
        icon,
        props.href,
        schema,
        Designer
    ]);
    pushMenuItem(item);
    return null;
}, {
    displayName: 'MenuURL'
});
Menu_Menu.SubMenu = observer((props)=>{
    const { t } = useMenuTranslation();
    const { Component, getMenuItems } = useMenuItem();
    const { pushMenuItem } = useCollectMenuItems();
    const { icon, children, ...others } = props;
    const schema = useFieldSchema();
    const field = useField();
    const mode = useContext(MenuModeContext);
    const Designer = useContext(MenuItemDesignerContext);
    const { styles } = useStyles();
    const submenu = useMemo(()=>({
            ...others,
            className: styles.menuItemClass,
            key: schema.name,
            eventKey: schema.name,
            menu: {
                icon,
                field,
                Designer,
                schema,
                styles
            },
            label: /*#__PURE__*/ jsx(SchemaContext.Provider, {
                value: schema,
                children: /*#__PURE__*/ jsx(FieldContext.Provider, {
                    value: field,
                    children: /*#__PURE__*/ jsx(SortableItem, {
                        className: styles.subMenuDesignerCss,
                        removeParentsIfNoChildren: false,
                        "aria-label": t(field.title),
                        overStyle: {
                            background: 'transparent'
                        },
                        children: /*#__PURE__*/ jsxs(DragHandleMenu, {
                            name: schema.name,
                            isSubMenu: true,
                            children: [
                                /*#__PURE__*/ jsxs("span", {
                                    className: 'submenu-title',
                                    children: [
                                        /*#__PURE__*/ jsx(Icon, {
                                            type: icon
                                        }),
                                        /*#__PURE__*/ jsx("span", {
                                            className: 'menuitem-title',
                                            children: t(field.title)
                                        })
                                    ]
                                }),
                                /*#__PURE__*/ jsx(Designer, {})
                            ]
                        })
                    })
                })
            }),
            children: getMenuItems(()=>/*#__PURE__*/ jsx(RecursionField, {
                    schema: schema,
                    onlyRenderProperties: true
                }))
        }), [
        field.title,
        icon,
        schema,
        children,
        Designer
    ]);
    if (!pushMenuItem) {
        error('Menu.SubMenu must be wrapped by GetMenuItemsContext.Provider');
        return null;
    }
    if ('mix' === mode) return /*#__PURE__*/ jsx(Menu_Menu.Item, {
        ...props
    });
    pushMenuItem(submenu);
    return /*#__PURE__*/ jsx(Component, {});
}, {
    displayName: 'Menu.SubMenu'
});
Menu_Menu.Designer = MenuDesigner;
export { Menu_Menu as Menu };
