/**
 * amis-ui v6.14.0-beta.1
 * Copyright 2018-2025 fex
 */

import { __extends, __assign, __rest, __decorate, __metadata } from 'tslib';
import React__default from 'react';
import Transition, { ENTERING, ENTERED, EXITING, EXITED } from 'react-transition-group/Transition';
import Portal from 'react-overlays/Portal';
import { current, removeModal, addModal } from './ModalManager.js';
import { getScrollbarWidth, themeable, localeable, autobind } from 'amis-core';
import { Icon } from './icons.js';
import { DraggableCore } from 'react-draggable';
import isNumber from 'lodash/isNumber';

/**
 * @file Modal
 * @description
 * @author fex
 */
var _a, _b;
var getContainerWithFullscreen = function (container) { return function () {
    var envContainer = typeof container === 'function' ? container() : container;
    // 获取当前全屏元素
    var fullscreenElement = document.fullscreenElement;
    if (fullscreenElement &&
        (!envContainer || !fullscreenElement.contains(envContainer))) {
        return fullscreenElement;
    }
    return envContainer || null;
}; };
var fadeStyles = (_a = {},
    _a[ENTERING] = 'in',
    _a[ENTERED] = 'in',
    _a[EXITING] = 'out',
    _a);
var contentFadeStyles = (_b = {},
    _b[ENTERING] = 'in',
    _b[ENTERED] = '',
    _b[EXITING] = 'out',
    _b);
var Modal = /** @class */ (function (_super) {
    __extends(Modal, _super);
    function Modal() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.isRootClosed = false;
        _this.state = { dragPos: undefined };
        _this.handleEnter = function () {
            document.body.classList.add("is-modalOpened");
            if (window.innerWidth - document.documentElement.clientWidth > 0 ||
                document.body.scrollHeight > document.body.clientHeight) {
                var scrollbarWidth = getScrollbarWidth();
                document.body.style.width = "calc(100% - ".concat(scrollbarWidth, "px)");
            }
        };
        _this.handleEntered = function () {
            var onEntered = _this.props.onEntered;
            document.body.addEventListener('mousedown', _this.handleRootMouseDownCapture, true);
            document.body.addEventListener('mouseup', _this.handleRootMouseUpCapture, true);
            document.body.addEventListener('mouseup', _this.handleRootMouseUp);
            onEntered && onEntered();
        };
        _this.handleExited = function () {
            var onExited = _this.props.onExited;
            document.body.removeEventListener('mouseup', _this.handleRootMouseUp);
            document.body.removeEventListener('mousedown', _this.handleRootMouseDownCapture, true);
            document.body.removeEventListener('mouseup', _this.handleRootMouseUpCapture, true);
            onExited && onExited();
            setTimeout(function () {
                if (!document.querySelector('.amis-dialog-widget')) {
                    document.body.classList.remove("is-modalOpened");
                    document.body.style.width = '';
                }
            }, 200);
        };
        _this.modalRef = function (ref) {
            _this.modalDom = ref;
            var ns = _this.props.classPrefix;
            if (ref) {
                addModal(_this);
                ref.classList.add("".concat(ns, "Modal--").concat(current(), "th"));
            }
            else {
                removeModal(_this);
            }
        };
        // #region 处理dialog拖动
        _this.handleDragStart = function (_event, uiData) {
            var node = uiData.node;
            var offsetParent = node.offsetParent;
            if (!node || !offsetParent) {
                return;
            }
            var _a = window.document.documentElement, clientWidth = _a.clientWidth, clientHeight = _a.clientHeight;
            var nodeStyle = getComputedStyle(node);
            var marginTop = parseInt(nodeStyle.marginTop, 10);
            var nodeWidth = parseInt(nodeStyle.width, 10);
            var nodeHeight = parseInt(nodeStyle.height, 10);
            var bounds = {
                left: 0,
                right: clientWidth - nodeWidth,
                top: -marginTop,
                bottom: clientHeight - nodeHeight - marginTop
            };
            var parentRect = offsetParent.getBoundingClientRect();
            var clientRect = node.getBoundingClientRect();
            var cLeft = clientRect.left;
            var pLeft = parentRect.left;
            var cTop = clientRect.top;
            var pTop = parentRect.top;
            var left = cLeft - pLeft + offsetParent.scrollLeft;
            var top = cTop - pTop + offsetParent.scrollTop - marginTop;
            _this.setState({ dragPos: { x: left, y: top }, bounds: bounds });
            // 阻止冒泡  存在弹窗里面套弹窗
            _event.stopPropagation();
        };
        _this.handleDrag = function (e, _a) {
            var deltaX = _a.deltaX, deltaY = _a.deltaY;
            e.stopPropagation();
            if (!_this.state.dragPos) {
                return;
            }
            var _b = _this.state, _c = _b.dragPos, x = _c.x, y = _c.y, bounds = _b.bounds;
            var calcY = y + deltaY;
            var calcX = x + deltaX;
            // 防止拖动到屏幕外 处理边界
            if (isNumber(bounds === null || bounds === void 0 ? void 0 : bounds.right)) {
                calcX = Math.min(calcX, bounds.right);
            }
            if (isNumber(bounds === null || bounds === void 0 ? void 0 : bounds.bottom)) {
                calcY = Math.min(calcY, bounds.bottom);
            }
            if (isNumber(bounds === null || bounds === void 0 ? void 0 : bounds.left)) {
                calcX = Math.max(calcX, bounds.left);
            }
            if (isNumber(bounds === null || bounds === void 0 ? void 0 : bounds.top)) {
                calcY = Math.max(calcY, bounds.top);
            }
            _this.setState({ dragPos: { x: calcX, y: calcY } });
        };
        _this.handleDragStop = function (e) {
            e.stopPropagation();
        };
        _this.getDragStyle = function () {
            var draggable = _this.props.draggable;
            var dragPos = _this.state.dragPos;
            if (!dragPos || !draggable) {
                return {};
            }
            var x = dragPos.x, y = dragPos.y;
            return {
                top: "".concat(y, "px"),
                left: "".concat(x, "px"),
                position: 'absolute'
            };
        };
        return _this;
    }
    Modal.prototype.componentDidMount = function () {
        if (this.props.show) {
            this.handleEnter();
            this.handleEntered();
        }
    };
    Modal.prototype.componentWillUnmount = function () {
        if (this.props.show) {
            this.handleExited();
        }
    };
    Modal.prototype.handleRootMouseDownCapture = function (e) {
        var target = e.target;
        var _a = this.props, closeOnOutside = _a.closeOnOutside, ns = _a.classPrefix, mobileUI = _a.mobileUI;
        var isLeftButton = (e.button === 1 && window.event !== null) || e.button === 0;
        this.isRootClosed = !!(isLeftButton &&
            closeOnOutside &&
            target &&
            this.modalDom &&
            ((!mobileUI &&
                !this.modalDom.contains(target) &&
                !target.closest('[role=dialog]')) ||
                (target.matches(".".concat(ns, "Modal")) && target === this.modalDom))); // 干脆过滤掉来自弹框里面的点击
    };
    Modal.prototype.handleRootMouseUpCapture = function (e) {
        // mousedown 的时候不在弹窗里面，则不需要判断了
        if (!this.isRootClosed) {
            return;
        }
        // 再判断 mouseup 的时候是不是在弹窗里面
        this.handleRootMouseDownCapture(e);
    };
    Modal.prototype.handleRootMouseUp = function (e) {
        var onHide = this.props.onHide;
        this.isRootClosed && !e.defaultPrevented && onHide(e);
    };
    // #endregion
    Modal.prototype.render = function () {
        var _this = this;
        var _a = this.props, className = _a.className, contentClassName = _a.contentClassName, children = _a.children, container = _a.container, show = _a.show, size = _a.size, style = _a.style, overlay = _a.overlay, width = _a.width, height = _a.height, modalClassName = _a.modalClassName, modalMaskClassName = _a.modalMaskClassName, cx = _a.classnames, mobileUI = _a.mobileUI, draggable = _a.draggable, classPrefix = _a.classPrefix;
        var _style = {
            width: (style === null || style === void 0 ? void 0 : style.width) ? style === null || style === void 0 ? void 0 : style.width : width,
            height: (style === null || style === void 0 ? void 0 : style.height) ? style === null || style === void 0 ? void 0 : style.height : height
        };
        return (React__default.createElement(Transition, { mountOnEnter: true, unmountOnExit: true, appear: true, in: show, timeout: 500, onEnter: this.handleEnter, onExited: this.handleExited, onEntered: this.handleEntered }, function (status) {
            var _a;
            return (React__default.createElement(Portal, { container: getContainerWithFullscreen(container) },
                React__default.createElement("div", { ref: _this.modalRef, role: "dialog", className: cx("amis-dialog-widget Modal", (_a = {},
                        _a["Modal--".concat(size)] = size,
                        _a), className) },
                    overlay ? (React__default.createElement("div", { className: cx("Modal-overlay", fadeStyles[status], modalMaskClassName) })) : null,
                    React__default.createElement(DraggableCore, { disabled: !draggable || mobileUI, onStart: _this.handleDragStart, onDrag: _this.handleDrag, onStop: _this.handleDragStop, cancel: "Icon, svg, a, svg *", handle: ".".concat(classPrefix, "Modal-header") },
                        React__default.createElement("div", { className: cx("Modal-content", draggable && !mobileUI ? 'Modal-draggable' : '', size === 'custom' ? 'Modal-content-custom' : '', contentClassName, modalClassName, contentFadeStyles[status]), style: __assign(__assign({}, _style), _this.getDragStyle()) }, status === EXITED ? null : children)))));
        }));
    };
    Modal.defaultProps = {
        container: document.body,
        size: '',
        overlay: true,
        draggable: false
    };
    Modal.Header = themeable(localeable(function (_a) {
        var cx = _a.classnames, className = _a.className, showCloseButton = _a.showCloseButton, onClose = _a.onClose, children = _a.children; _a.classPrefix; var __ = _a.translate; _a.forwardedRef; var rest = __rest(_a, ["classnames", "className", "showCloseButton", "onClose", "children", "classPrefix", "translate", "forwardedRef"]);
        return (React__default.createElement("div", __assign({}, rest, { className: cx('Modal-header', className) }),
            showCloseButton !== false ? (React__default.createElement("a", { "data-tooltip": __('Dialog.close'), "data-position": "left", onClick: onClose, className: cx('Modal-close') },
                React__default.createElement(Icon, { icon: "close", className: "icon" }))) : null,
            children));
    }));
    Modal.Title = themeable(function (_a) {
        var cx = _a.classnames, className = _a.className, children = _a.children; _a.classPrefix; _a.forwardedRef; var rest = __rest(_a, ["classnames", "className", "children", "classPrefix", "forwardedRef"]);
        return (React__default.createElement("div", __assign({}, rest, { className: cx('Modal-title', className) }), children));
    });
    Modal.Body = themeable(function (_a) {
        var cx = _a.classnames, className = _a.className, children = _a.children; _a.classPrefix; _a.forwardedRef; var rest = __rest(_a, ["classnames", "className", "children", "classPrefix", "forwardedRef"]);
        return (React__default.createElement("div", __assign({}, rest, { className: cx('Modal-body', className) }), children));
    });
    Modal.Footer = themeable(function (_a) {
        var cx = _a.classnames, className = _a.className, children = _a.children; _a.classPrefix; _a.forwardedRef; var rest = __rest(_a, ["classnames", "className", "children", "classPrefix", "forwardedRef"]);
        return (React__default.createElement("div", __assign({}, rest, { className: cx('Modal-footer', className) }), children));
    });
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Modal.prototype, "handleRootMouseDownCapture", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Modal.prototype, "handleRootMouseUpCapture", null);
    __decorate([
        autobind,
        __metadata("design:type", Function),
        __metadata("design:paramtypes", [MouseEvent]),
        __metadata("design:returntype", void 0)
    ], Modal.prototype, "handleRootMouseUp", null);
    return Modal;
}(React__default.Component));
var FinalModal = themeable(localeable(Modal));

export { Modal, FinalModal as default, getContainerWithFullscreen };
