"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const vueuc_1 = require("vueuc");
const vooks_1 = require("vooks");
const icons_1 = require("../../_internal/icons");
const _utils_1 = require("../../_utils");
const icon_1 = require("../../icon");
const DropdownMenu_1 = require("./DropdownMenu");
const Dropdown_1 = require("./Dropdown");
const utils_1 = require("./utils");
const dropdownOptionInjectionKey = Symbol('dropdown-option');
exports.default = vue_1.defineComponent({
    name: 'DropdownOption',
    props: {
        clsPrefix: {
            type: String,
            required: true
        },
        tmNode: {
            type: Object,
            required: true
        },
        parentKey: {
            type: [String, Number],
            default: null
        },
        placement: {
            type: String,
            default: 'right-start'
        }
    },
    setup(props) {
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const NDropdown = vue_1.inject(Dropdown_1.dropdownInjectionKey);
        const { hoverKeyRef, keyboardKeyRef, lastToggledSubmenuKeyRef, pendingKeyPathRef, activeKeyPathRef, animatedRef, mergedShowRef, renderLabelRef, renderIconRef } = NDropdown;
        const NDropdownOption = vue_1.inject(dropdownOptionInjectionKey, null);
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const NDropdownMenu = vue_1.inject(DropdownMenu_1.dropdownMenuInjectionKey);
        const rawNodeRef = vue_1.computed(() => props.tmNode.rawNode);
        const hasSubmenuRef = vue_1.computed(() => {
            return utils_1.isSubmenuNode(props.tmNode.rawNode);
        });
        const mergedDisabledRef = vue_1.computed(() => {
            const { disabled } = props.tmNode;
            return disabled;
        });
        const showSubmenuRef = vue_1.computed(() => {
            if (!hasSubmenuRef.value)
                return false;
            const { key, disabled } = props.tmNode;
            if (disabled)
                return false;
            const { value: hoverKey } = hoverKeyRef;
            const { value: keyboardKey } = keyboardKeyRef;
            const { value: lastToggledSubmenuKey } = lastToggledSubmenuKeyRef;
            const { value: pendingKeyPath } = pendingKeyPathRef;
            if (hoverKey !== null)
                return pendingKeyPath.includes(key);
            if (keyboardKey !== null) {
                return (pendingKeyPath.includes(key) &&
                    pendingKeyPath[pendingKeyPath.length - 1] !== key);
            }
            if (lastToggledSubmenuKey !== null)
                return pendingKeyPath.includes(key);
            return false;
        });
        const shouldDelayRef = vue_1.computed(() => {
            return keyboardKeyRef.value === null && !animatedRef.value;
        });
        const deferredShowSubmenuRef = _utils_1.useDeferredTrue(showSubmenuRef, 300, shouldDelayRef);
        const parentEnteringSubmenuRef = vue_1.computed(() => {
            return !!(NDropdownOption === null || NDropdownOption === void 0 ? void 0 : NDropdownOption.enteringSubmenuRef.value);
        });
        const enteringSubmenuRef = vue_1.ref(false);
        vue_1.provide(dropdownOptionInjectionKey, {
            enteringSubmenuRef
        });
        // methods
        function handleSubmenuBeforeEnter() {
            enteringSubmenuRef.value = true;
        }
        function handleSubmenuAfterEnter() {
            enteringSubmenuRef.value = false;
        }
        function handleMouseEnter() {
            const { parentKey, tmNode } = props;
            if (!mergedShowRef.value)
                return;
            lastToggledSubmenuKeyRef.value = parentKey;
            keyboardKeyRef.value = null;
            hoverKeyRef.value = tmNode.key;
        }
        function handleMouseMove() {
            const { tmNode } = props;
            if (!mergedShowRef.value)
                return;
            if (hoverKeyRef.value === tmNode.key)
                return;
            handleMouseEnter();
        }
        function handleMouseLeave(e) {
            if (!mergedShowRef.value)
                return;
            const { relatedTarget } = e;
            if (relatedTarget &&
                !relatedTarget.hasAttribute('__dropdown-option')) {
                hoverKeyRef.value = null;
            }
        }
        function handleClick() {
            const { value: hasSubmenu } = hasSubmenuRef;
            const { tmNode } = props;
            if (!mergedShowRef.value)
                return;
            if (!hasSubmenu && !tmNode.disabled) {
                NDropdown.doSelect(tmNode.key, tmNode.rawNode);
                NDropdown.doUpdateShow(false);
            }
        }
        return {
            renderLabel: renderLabelRef,
            renderIcon: renderIconRef,
            siblingHasIcon: NDropdownMenu.showIconRef,
            siblingHasSubmenu: NDropdownMenu.hasSubmenuRef,
            animated: animatedRef,
            mergedShowSubmenu: vue_1.computed(() => {
                return deferredShowSubmenuRef.value && !parentEnteringSubmenuRef.value;
            }),
            rawNode: rawNodeRef,
            hasSubmenu: hasSubmenuRef,
            pending: vooks_1.useMemo(() => {
                const { value: pendingKeyPath } = pendingKeyPathRef;
                const { key } = props.tmNode;
                return pendingKeyPath.includes(key);
            }),
            childActive: vooks_1.useMemo(() => {
                const { value: activeKeyPath } = activeKeyPathRef;
                const { key } = props.tmNode;
                const index = activeKeyPath.findIndex((k) => key === k);
                if (index === -1)
                    return false;
                return index < activeKeyPath.length - 1;
            }),
            active: vooks_1.useMemo(() => {
                const { value: activeKeyPath } = activeKeyPathRef;
                const { key } = props.tmNode;
                const index = activeKeyPath.findIndex((k) => key === k);
                if (index === -1)
                    return false;
                return index === activeKeyPath.length - 1;
            }),
            mergedDisabled: mergedDisabledRef,
            handleClick,
            handleMouseMove,
            handleMouseEnter,
            handleMouseLeave,
            handleSubmenuBeforeEnter,
            handleSubmenuAfterEnter
        };
    },
    render() {
        var _a;
        const { animated, rawNode, mergedShowSubmenu, clsPrefix, siblingHasIcon, siblingHasSubmenu, renderLabel, renderIcon } = this;
        const submenuVNode = mergedShowSubmenu ? (vue_1.h(DropdownMenu_1.default, { clsPrefix: clsPrefix, tmNodes: this.tmNode.children, parentKey: this.tmNode.key })) : null;
        return (vue_1.h("div", { class: `${clsPrefix}-dropdown-option` },
            vue_1.h("div", { class: [
                    `${clsPrefix}-dropdown-option-body`,
                    {
                        [`${clsPrefix}-dropdown-option-body--pending`]: this.pending,
                        [`${clsPrefix}-dropdown-option-body--active`]: this.active,
                        [`${clsPrefix}-dropdown-option-body--child-active`]: this.childActive,
                        [`${clsPrefix}-dropdown-option-body--disabled`]: this.mergedDisabled
                    }
                ], onMousemove: this.handleMouseMove, onMouseenter: this.handleMouseEnter, onMouseleave: this.handleMouseLeave, onClick: this.handleClick },
                vue_1.h("div", { "__dropdown-option": true, class: [
                        `${clsPrefix}-dropdown-option-body__prefix`,
                        siblingHasIcon &&
                            `${clsPrefix}-dropdown-option-body__prefix--show-icon`
                    ] }, renderIcon ? renderIcon(rawNode) : _utils_1.render(rawNode.icon)),
                vue_1.h("div", { "__dropdown-option": true, class: `${clsPrefix}-dropdown-option-body__label` }, renderLabel
                    ? renderLabel(rawNode)
                    : _utils_1.render((_a = rawNode.label) !== null && _a !== void 0 ? _a : rawNode.title)),
                vue_1.h("div", { "__dropdown-option": true, class: [
                        `${clsPrefix}-dropdown-option-body__suffix`,
                        siblingHasSubmenu &&
                            `${clsPrefix}-dropdown-option-body__suffix--has-submenu`
                    ] }, this.hasSubmenu ? (vue_1.h(icon_1.NIcon, null, {
                    default: () => vue_1.h(icons_1.ChevronRightIcon, null)
                })) : null)),
            this.hasSubmenu ? (vue_1.h(vueuc_1.VBinder, null, {
                default: () => [
                    vue_1.h(vueuc_1.VTarget, null, {
                        default: () => (vue_1.h("div", { class: `${clsPrefix}-dropdown-offset-container` },
                            vue_1.h(vueuc_1.VFollower, { show: this.mergedShowSubmenu, placement: this.placement, teleportDisabled: true }, {
                                default: () => {
                                    return (vue_1.h("div", { class: `${clsPrefix}-dropdown-menu-wrapper` }, animated ? (vue_1.h(vue_1.Transition, { onBeforeEnter: this.handleSubmenuBeforeEnter, onAfterEnter: this.handleSubmenuAfterEnter, name: "fade-in-scale-up-transition", appear: true }, {
                                        default: () => submenuVNode
                                    })) : (submenuVNode)));
                                }
                            })))
                    })
                ]
            })) : null));
    }
});
