import { __assign, __spreadArray } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import { cloneElement, createContext, useContext, useEffect, useMemo, useRef, } from 'react';
import { Subject, Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import Context from '../Context';
import Anchor from '../Anchor';
import { addEventListener } from '../../utils/component/event-handler';
import { isElement, isFragment } from 'react-is';
export var PopoverHoverTriggerContext = createContext({
    fixMouseEventsOnDisabledChildren: false,
});
export function PopoverHoverTrigger(props) {
    var ctx = useContext(Context);
    if (!ctx) {
        throw new Error('PopoverHoverTrigger must be child of Popover');
    }
    var propsRef = useRef(props);
    propsRef.current = props;
    var visible$ = useMemo(function () { return new Subject(); }, []);
    useEffect(function () {
        var $ = visible$
            .pipe(switchMap(function (visible) {
            var _a = propsRef.current, _b = _a.hideDelay, hideDelay = _b === void 0 ? 150 : _b, _c = _a.showDelay, showDelay = _c === void 0 ? 150 : _c;
            return new Observable(function (subscriber) {
                var timer = setTimeout(function () {
                    subscriber.next(visible);
                    subscriber.complete();
                    timer = null;
                }, visible ? showDelay : hideDelay);
                return function () {
                    timer && clearTimeout(timer);
                };
            });
        }))
            .subscribe(function (visible) {
            ctx.popover.setVisible(visible);
        });
        return function () { return $.unsubscribe(); };
    }, [ctx.popover, visible$]);
    var children = props.children, _a = props.fixMouseEventsOnDisabledChildren, fixMouseEventsOnDisabledChildren = _a === void 0 ? false : _a;
    var portalRef = ctx.portalRef, didMount = ctx.didMount;
    didMount(function () {
        var container = portalRef.current.container;
        function onMouseEnter() {
            var anchorOnly = propsRef.current.anchorOnly;
            if (anchorOnly) {
                return;
            }
            visible$.next(true);
        }
        function onMouseLeave() {
            var anchorOnly = propsRef.current.anchorOnly;
            if (anchorOnly) {
                return;
            }
            visible$.next(false);
        }
        function onWindowBlur() {
            visible$.next(false);
        }
        var disposers = [
            addEventListener(container, 'mouseenter', onMouseEnter),
            addEventListener(container, 'mouseleave', onMouseLeave),
            addEventListener(window, 'blur', onWindowBlur),
        ];
        return function () {
            disposers.forEach(function (dispose) { return dispose(); });
        };
    });
    var child;
    if (typeof children === 'function') {
        child = children({
            onMouseEnter: function () {
                visible$.next(true);
            },
            onMouseLeave: function () {
                visible$.next(false);
            },
        });
    }
    else if (isElement(children) && !isFragment(children)) {
        var elem_1 = children;
        child = cloneElement(elem_1, {
            onMouseEnter: function () {
                var _a, _b;
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                (_b = (_a = elem_1.props).onMouseEnter) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a], args));
                visible$.next(true);
            },
            onMouseLeave: function () {
                var _a, _b;
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                (_b = (_a = elem_1.props).onMouseLeave) === null || _b === void 0 ? void 0 : _b.call.apply(_b, __spreadArray([_a], args));
                visible$.next(false);
            },
        });
    }
    else {
        child = (_jsx("span", __assign({ onMouseEnter: function () { return visible$.next(true); }, onMouseLeave: function () { return visible$.next(false); }, "data-zv": 'v10.0.12' }, { children: children }), void 0));
    }
    return (_jsx(PopoverHoverTriggerContext.Provider, __assign({ value: { fixMouseEventsOnDisabledChildren: fixMouseEventsOnDisabledChildren } }, { children: _jsx(Anchor, __assign({ getElement: props.getElement }, { children: child }), void 0) }), void 0));
}
export default PopoverHoverTrigger;
