import { __assign, __extends } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
import { Component, createRef } from 'react';
import * as Position from './placement';
import PopoverContent from './Content';
import Trigger from './trigger';
import PopoverContext from './Context';
import withPopover from './withPopover';
import Anchor from './Anchor';
var Popover = (function (_super) {
    __extends(Popover, _super);
    function Popover() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.getAnchor = null;
        _this.isUnmounted = false;
        _this.pendingOnBeforeHook = false;
        _this.didMountHooks = [];
        _this.didMountCleanup = [];
        _this.portalRef = createRef();
        _this.isPositionReady = false;
        _this.contentRef = createRef();
        _this.state = {
            visible: false,
        };
        _this.escape = function () {
            _this.pendingOnBeforeHook = false;
        };
        _this.didMount = function (cb) {
            _this.didMountHooks.push(cb);
        };
        _this.open = function () {
            _this.setVisible(true);
        };
        _this.close = function () {
            _this.setVisible(false);
        };
        return _this;
    }
    Popover.prototype.setVisible = function (visible) {
        var _this = this;
        var _a = this.props, onBeforeClose = _a.onBeforeClose, onBeforeShow = _a.onBeforeShow, onVisibleChange = _a.onVisibleChange;
        var hook = visible ? onBeforeShow : onBeforeClose;
        if (this.pendingOnBeforeHook || visible === this.state.visible) {
            return;
        }
        if (onVisibleChange) {
            return onVisibleChange(visible);
        }
        if (!hook) {
            return this.safeSetState({ visible: visible });
        }
        this.pendingOnBeforeHook = true;
        var continuation = function () {
            _this.safeSetState({
                visible: visible,
            });
            _this.pendingOnBeforeHook = false;
        };
        if (hook.length >= 1) {
            return hook(continuation, this.escape);
        }
        Promise.resolve(hook()).then(continuation, this.escape);
    };
    Popover.prototype.adjustPosition = function () {
        var _a;
        (_a = this.contentRef.current) === null || _a === void 0 ? void 0 : _a.adjustPosition();
    };
    Popover.prototype.positionUpdated = function () {
        var _a = this.props, onPositionReady = _a.onPositionReady, onPositionUpdated = _a.onPositionUpdated;
        onPositionUpdated === null || onPositionUpdated === void 0 ? void 0 : onPositionUpdated();
        if (!this.isPositionReady) {
            this.isPositionReady = true;
            onPositionReady === null || onPositionReady === void 0 ? void 0 : onPositionReady();
        }
    };
    Popover.prototype.safeSetState = function (nextState, callback) {
        if (!this.isUnmounted) {
            return this.setState(nextState, callback);
        }
    };
    Popover.getDerivedStateFromProps = function (props) {
        if (typeof props.visible === 'boolean') {
            return {
                visible: props.visible,
            };
        }
        return null;
    };
    Popover.prototype.componentDidMount = function () {
        var onShow = this.props.onShow;
        if (this.state.visible) {
            onShow && onShow();
        }
        this.didMountCleanup = this.didMountHooks.map(function (it) { return it(); });
    };
    Popover.prototype.componentDidUpdate = function (prevProps, prevState) {
        if (prevState.visible !== this.state.visible) {
            var _a = this.props, onShow = _a.onShow, onClose = _a.onClose;
            if (this.state.visible) {
                this.isPositionReady = false;
                onShow && onShow();
            }
            else {
                onClose && onClose();
            }
        }
        this.adjustPosition();
    };
    Popover.prototype.componentWillUnmount = function () {
        this.isUnmounted = true;
        this.didMountCleanup.forEach(function (it) { return it(); });
    };
    Popover.prototype.render = function () {
        var _a = this.props, containerSelector = _a.containerSelector, position = _a.position, cushion = _a.cushion, className = _a.className, children = _a.children, style = _a.style;
        var visible = this.state.visible;
        return (_jsx(PopoverContext.Provider, __assign({ value: {
                visible: visible,
                containerSelector: containerSelector,
                placement: position,
                cushion: cushion,
                className: className,
                portalRef: this.portalRef,
                contentRef: this.contentRef,
                popover: this,
                didMount: this.didMount,
                style: style,
            } }, { children: children }), void 0));
    };
    Popover.contextType = PopoverContext;
    Popover.defaultProps = {
        cushion: 0,
        containerSelector: 'body',
    };
    Popover.Anchor = Anchor;
    Popover.Content = PopoverContent;
    Popover.Trigger = Trigger;
    Popover.Position = Position;
    Popover.withPopover = withPopover;
    Popover.Context = PopoverContext;
    return Popover;
}(Component));
export { Popover };
export default Popover;
