"use strict";
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);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-explicit-any */
var noop_1 = __importDefault(require("lodash/noop"));
var find_1 = __importDefault(require("lodash/find"));
var map_1 = __importDefault(require("lodash/map"));
var react_1 = __importStar(require("react"));
var themed_components_1 = __importStar(require("@monstrosity/utilities/themed-components"));
var disable_scroll_1 = require("@monstrosity/utilities/disable-scroll/disable-scroll");
var mask_1 = require("../../core/Mask/mask");
var Context = react_1.createContext({
    'closePopout': noop_1.default,
    'showPopout': noop_1.default,
});
var Root = themed_components_1.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 = themed_components_1.default.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_1.default(_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_1.default.createElement(Root, { initialPose: 'hidden', pose: currentQueueItem ? 'visible' : 'hidden' },
                    currentQueueItem && react_1.default.createElement(disable_scroll_1.DisableScroll, null),
                    react_1.default.createElement(ScreenWrapper, null,
                        react_1.default.createElement(mask_1.Mask, { onClick: currentQueueItem.onMaskClick, isVisible: !!currentQueueItem, opacity: currentQueueItem.opacity }),
                        currentQueueItem.content)));
            }
            /* Desktop - Stack all Modals */
            return map_1.default(_this.queue, function (item) {
                return (react_1.default.createElement(Root, { initialPose: 'hidden', pose: item ? 'visible' : 'hidden', key: item.key },
                    item && react_1.default.createElement(disable_scroll_1.DisableScroll, null),
                    react_1.default.createElement(ScreenWrapper, null,
                        react_1.default.createElement(mask_1.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_1.default.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;
}(react_1.Component));
exports.PopoutProvider = PopoutProvider;
exports.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_1.default,
            'onClosePopout': onClosePopout(props),
        }),
        id: id,
        onClose: onClose,
        'onMaskClick': props.closePopout || noop_1.default,
        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_1.default.createElement(Context.Consumer, null, function (props) { return children({
        'onShowPopout': onShowPopout(props),
        'onClosePopout': onClosePopout(props),
    }); }));
};
var templateObject_1;
