var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
/* eslint-disable @typescript-eslint/no-explicit-any */
import noop from 'lodash/noop';
import find from 'lodash/find';
import map from 'lodash/map';
import React, { Component, createContext } from 'react';
import styled, { posed } from '@monstrosity/utilities/themed-components';
import { DisableScroll } from '@monstrosity/utilities/disable-scroll/disable-scroll';
import { Mask } from '../../core/Mask/mask';
var Context = createContext({
    'closePopout': noop,
    'showPopout': noop,
});
var Root = posed.div({
    'hidden': {
        'applyAtEnd': {
            'display': 'none',
        },
        'height': 0,
        'opacity': 0,
        'transition': {
            'opacity': { 'ease': 'easeOut', 'duration': 200 },
        },
    },
    'visible': {
        'applyAtStart': { 'display': 'block', 'position': 'fixed' },
        'height': 'auto',
        'opacity': 1,
        'transition': {
            'opacity': { 'ease': 'easeIn', 'duration': 110 },
        },
    },
});
var ScreenWrapper = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n\tposition: fixed;\n\tz-index: ", ";\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: flex;\n\toverflow-x: hidden;\n\toverflow-y: auto;\n\tflex-direction: column;\n\tpadding: 2rem;\n\talign-items: center;\n\tjustify-content: center; /* Should all of this be here */\n\n\t& :nth-child(2) {\n\t\tz-index: ", ";\n\t}\n"], ["\n\tposition: fixed;\n\tz-index: ", ";\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\tleft: 0;\n\tdisplay: flex;\n\toverflow-x: hidden;\n\toverflow-y: auto;\n\tflex-direction: column;\n\tpadding: 2rem;\n\talign-items: center;\n\tjustify-content: center; /* Should all of this be here */\n\n\t& :nth-child(2) {\n\t\tz-index: ", ";\n\t}\n"])), function (_a) {
    var theme = _a.theme;
    return theme.zIndex.modal;
}, function (_a) {
    var theme = _a.theme;
    return theme.zIndex.modalContent;
});
var PopoutProvider = /** @class */ (function (_super) {
    __extends(PopoutProvider, _super);
    function PopoutProvider() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.state = {
            'selectedKey': undefined,
        };
        _this.queue = [];
        _this.show = function (request, closeable) {
            if (closeable === void 0) { closeable = true; }
            var newPopout = __assign(__assign({}, request), { closeable: closeable, 'key': request.id.toString() });
            var popout = find(_this.queue, function (queuedItem) { return queuedItem.key === request.id; }) || newPopout;
            popout.content = request.content;
            popout.onClose = request.onClose;
            popout.onMaskClick = request.onMaskClick;
            _this.updateCurrentlyShowing(popout);
            /* This line can be better */
            if (newPopout === popout)
                _this.queue = _this.queue.concat(newPopout);
            return popout.key;
        };
        _this.close = function () { return _this.onClose(); };
        _this.renderQueueItems = function (currentQueueItem) {
            /* Mobile - Render One at a Time */
            if (currentQueueItem && _this.props.isMobile) {
                return (React.createElement(Root, { initialPose: 'hidden', pose: currentQueueItem ? 'visible' : 'hidden' },
                    currentQueueItem && React.createElement(DisableScroll, null),
                    React.createElement(ScreenWrapper, null,
                        React.createElement(Mask, { onClick: currentQueueItem.onMaskClick, isVisible: !!currentQueueItem, opacity: currentQueueItem.opacity }),
                        currentQueueItem.content)));
            }
            /* Desktop - Stack all Modals */
            return map(_this.queue, function (item) {
                return (React.createElement(Root, { initialPose: 'hidden', pose: item ? 'visible' : 'hidden', key: item.key },
                    item && React.createElement(DisableScroll, null),
                    React.createElement(ScreenWrapper, null,
                        React.createElement(Mask, { onClick: item.onMaskClick, isVisible: !!item, opacity: item.opacity }),
                        item.content)));
            });
        };
        _this.onClose = function () {
            var currentlyShowing = _this.currentlyShowing;
            if (currentlyShowing)
                _this.removeItem(currentlyShowing.key);
            if (!currentlyShowing || !currentlyShowing.onClose)
                return;
            currentlyShowing.onClose();
        };
        return _this;
    }
    PopoutProvider.prototype.render = function () {
        var current = this.currentlyShowing;
        return (React.createElement(Context.Provider, { value: __assign(__assign({}, this.state), { 'closePopout': this.close, 'showPopout': this.show }) },
            this.props.children,
            this.renderQueueItems(current)));
    };
    PopoutProvider.prototype.removeItem = function (key) {
        if (this.currentlyShowing && this.currentlyShowing.key === key) {
            this.queue = this.queue.slice(0, -1);
            this.updateCurrentlyShowing(this.queue.slice(-1)[0]);
        }
    };
    PopoutProvider.prototype.updateCurrentlyShowing = function (item) {
        this.currentlyShowing = item;
        this.setState({
            'selectedKey': item ? item.key : undefined,
        });
    };
    return PopoutProvider;
}(Component));
export { PopoutProvider };
export var Popoutable = function (_a) {
    var children = _a.children, content = _a.content, _b = _a.opacity, opacity = _b === void 0 ? 0.5 : _b, id = _a.id, afterClose = _a.afterClose;
    /* Check that child has methods to handle base props */
    var onClosePopout = function (props) { return function () {
        var closePopout = props.closePopout;
        if (closePopout)
            closePopout();
        if (afterClose)
            afterClose();
    }; };
    var onClose = function (closePopout) {
        if (closePopout)
            closePopout();
        if (afterClose)
            afterClose();
    };
    var request = function (props) { return ({
        'content': content({
            'onShowPopout': noop,
            'onClosePopout': onClosePopout(props),
        }),
        id: id,
        onClose: onClose,
        'onMaskClick': props.closePopout || noop,
        opacity: opacity,
    }); };
    var onShowPopout = function (props) { return function () {
        var showPopout = props.showPopout;
        /* To Do: Try Not to Recreate the request */
        if (showPopout)
            showPopout(request(props));
    }; };
    return (React.createElement(Context.Consumer, null, function (props) { return children({
        'onShowPopout': onShowPopout(props),
        'onClosePopout': onClosePopout(props),
    }); }));
};
var templateObject_1;
