import { defineComponent, ref, watch, nextTick, computed, createVNode, Teleport, Fragment, Transition, withDirectives, vShow } from 'vue';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import { isNumber } from 'lodash-es';
import getPrefixCls from '../_util/getPrefixCls';
import { FScrollbar } from '../scrollbar';
import FButton from '../button/button';
import { CloseOutlined } from '../icon';
import { useTheme } from '../_theme/useTheme';
import useEsc from '../_util/use/useEsc';
import PopupManager from '../_util/popupManager';
import useLockScreen from '../_util/use/useLockScreen';
import { useConfig } from '../config-provider';
import { useLocale } from '../config-provider/useLocale';
import { useContentMaxHeight } from './useContentMaxHeight';
import { globalModalProps, modalProps, modalIconMap } from './props';

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const prefixCls = getPrefixCls('modal');
const UPDATE_SHOW_EVENT = 'update:show';
const OK_EVENT = 'ok';
const CANCEL_EVENT = 'cancel';
const AFTER_ENTER_EVENT = 'after-enter';
const AFTER_LEAVE_EVENT = 'after-leave';
const Modal = defineComponent({
  name: 'FModal',
  props: _objectSpread(_objectSpread({}, globalModalProps), modalProps),
  emits: [UPDATE_SHOW_EVENT, OK_EVENT, CANCEL_EVENT, AFTER_ENTER_EVENT, AFTER_LEAVE_EVENT],
  setup(props, ctx) {
    useTheme();
    const zIndex = ref(PopupManager.nextZIndex());
    const visible = ref(false);
    useLockScreen(visible);
    watch(() => props.show, () => {
      if (props.show) {
        zIndex.value = PopupManager.nextZIndex();
      }
      nextTick(() => {
        visible.value = props.show;
      });
    }, {
      immediate: true
    });
    const config = useConfig();
    const getContainer = computed(() => {
      var _config$getContainer;
      return props.getContainer || ((_config$getContainer = config.getContainer) === null || _config$getContainer === void 0 ? void 0 : _config$getContainer.value);
    });
    const {
      t
    } = useLocale();
    function handleCancel(event) {
      ctx.emit(UPDATE_SHOW_EVENT, false);
      ctx.emit(CANCEL_EVENT, event);
    }
    const escClosable = computed(() => props.escClosable);
    useEsc(handleCancel, escClosable);
    function handleOk(event) {
      ctx.emit(OK_EVENT, event);
    }
    function handleTransitionAfterEnter(el) {
      ctx.emit(AFTER_ENTER_EVENT, el);
    }
    function handleTransitionAfterLeave(el) {
      ctx.emit(AFTER_LEAVE_EVENT, el);
    }
    const hasHeader = () => ctx.slots.title || props.title;
    function getHeader() {
      var _ctx$slots$title, _ctx$slots;
      const closeJsx = props.closable && createVNode("div", {
        "class": `${prefixCls}-close`,
        "onClick": handleCancel
      }, [createVNode(CloseOutlined, null, null)]);
      if (!hasHeader()) {
        return closeJsx;
      }
      const header = ((_ctx$slots$title = (_ctx$slots = ctx.slots).title) === null || _ctx$slots$title === void 0 ? void 0 : _ctx$slots$title.call(_ctx$slots)) || props.title;
      return createVNode("div", {
        "class": `${prefixCls}-header`,
        "ref": modalHeaderRef
      }, [props.type && createVNode("div", {
        "class": `${prefixCls}-icon ${prefixCls}-status-${props.type}`
      }, [props.type && modalIconMap[props.type]()]), createVNode("div", null, [header]), closeJsx]);
    }
    function getFooter() {
      if (!props.footer) {
        return null;
      }
      let footer = null;
      if (ctx.slots.footer) {
        footer = ctx.slots.footer();
      } else {
        footer = createVNode(Fragment, null, [props.showCancel && createVNode(FButton, {
          "size": "middle",
          "class": "btn-margin",
          "onClick": handleCancel,
          "loading": props.cancelLoading
        }, {
          default: () => [props.cancelText || t('modal.cancelText')]
        }), createVNode(FButton, {
          "type": "primary",
          "size": "middle",
          "onClick": handleOk,
          "loading": props.okLoading
        }, {
          default: () => [props.okText || t('modal.okText')]
        })]);
      }
      return createVNode("div", {
        "class": `${prefixCls}-footer`,
        "ref": modalFooterRef
      }, [footer]);
    }
    const styles = computed(() => {
      if (props.fullScreen) {
        return {};
      }
      return {
        width: isNumber(props.width) ? `${props.width}px` : props.width,
        marginTop: props.verticalCenter ? 0 : isNumber(props.top) ? `${props.top}px` : props.top,
        marginBottom: props.verticalCenter ? 0 : isNumber(props.bottom) ? `${props.bottom}px` : props.bottom
      };
    });

    // 获取最大的内容高度
    const {
      modalRef,
      modalHeaderRef,
      modalFooterRef,
      contentMaxHeight,
      hasMaxHeight
    } = useContentMaxHeight(styles, props);
    const getBody = () => {
      const modalBody = createVNode("div", {
        "class": `${prefixCls}-body`
      }, [ctx.slots.default ? ctx.slots.default() : props.forGlobal && props.content]);
      if (hasMaxHeight.value) {
        return createVNode(FScrollbar, {
          "maxHeight": contentMaxHeight.value,
          "shadow": true
        }, {
          default: () => [modalBody]
        });
      }
      return modalBody;
    };
    const showDom = computed(() => props.displayDirective === 'if' && visible.value || props.displayDirective === 'show');

    // 鼠标在弹窗内按下
    const mouseDownInsideChild = ref(false);

    // 遮罩层点击关闭的逻辑
    const handleClickMask = event => {
      if (props.maskClosable && props.mask && !mouseDownInsideChild.value) {
        handleCancel(event);
      }
      mouseDownInsideChild.value = false;
    };

    // 最外层类名
    const rootClass = computed(() => {
      return [prefixCls, props.wrapperClass].filter(Boolean);
    });
    const wrapperClass = computed(() => {
      return [`${prefixCls}-wrapper`, props.contentClass].filter(Boolean);
    });
    const renderMask = () => {
      return withDirectives(createVNode("div", {
        "class": `${prefixCls}-mask`,
        "style": {
          zIndex: zIndex.value
        }
      }, null), [[vShow, visible.value]]);
    };
    const renderContent = () => {
      return withDirectives(createVNode("div", {
        "class": {
          [`${prefixCls}-container`]: true,
          [`${prefixCls}-center`]: props.center,
          [`${prefixCls}-vertical-center`]: props.verticalCenter,
          [`${prefixCls}-fullscreen`]: props.fullScreen,
          [`${prefixCls}-global`]: props.forGlobal,
          [`${prefixCls}-no-header`]: !hasHeader(),
          [`${prefixCls}-no-footer`]: !props.footer
        },
        "style": {
          zIndex: zIndex.value
        },
        "onClick": event => handleClickMask(event)
      }, [createVNode("div", {
        "class": wrapperClass.value,
        "style": styles.value,
        "onClick": event => event.stopPropagation(),
        "onMousedown": () => {
          mouseDownInsideChild.value = true;
        },
        "onMouseup": () => {
          mouseDownInsideChild.value = false;
        },
        "ref": modalRef
      }, [getHeader(), getBody(), getFooter()])]), [[vShow, visible.value]]);
    };
    return () => {
      var _getContainer$value, _getContainer$value2;
      return createVNode(Teleport, {
        "disabled": !((_getContainer$value = getContainer.value) !== null && _getContainer$value !== void 0 && _getContainer$value.call(getContainer)),
        "to": (_getContainer$value2 = getContainer.value) === null || _getContainer$value2 === void 0 ? void 0 : _getContainer$value2.call(getContainer)
      }, {
        default: () => [createVNode("div", {
          "class": rootClass.value
        }, [props.useAnimation ? createVNode(Fragment, null, [createVNode(Transition, {
          "name": `${prefixCls}-mask-fade`
        }, {
          default: () => [props.mask && showDom.value && renderMask()]
        }), createVNode(Transition, {
          "name": `${prefixCls}-fade`,
          "onAfterEnter": handleTransitionAfterEnter,
          "onAfterLeave": handleTransitionAfterLeave
        }, {
          default: () => [showDom.value && renderContent()]
        })]) : createVNode(Fragment, null, [props.mask && showDom.value && renderMask(), showDom.value && renderContent()])])]
      });
    };
  }
});

export { Modal as default };
