import { isFunction, isString } from "../../../../../@vue/shared/dist/shared.esm-bundler.mjs";
import { TypeComponents, TypeComponentsMap } from "../../../utils/vue/icon.mjs";
import { isValidComponentSize } from "../../../utils/vue/validator.mjs";
import { useDraggable } from "../../../hooks/use-draggable/index.mjs";
import { useLockscreen } from "../../../hooks/use-lockscreen/index.mjs";
import { useSameTarget } from "../../../hooks/use-same-target/index.mjs";
import { useId } from "../../../hooks/use-id/index.mjs";
import { ElIcon } from "../../icon/index.mjs";
import focus_trap_default$1 from "../../focus-trap/index.mjs";
import { ElInput } from "../../input/index.mjs";
import { useGlobalComponentSettings } from "../../config-provider/src/hooks/use-global-config.mjs";
import { ElButton } from "../../button/index.mjs";
import TrapFocus from "../../../directives/trap-focus/index.mjs";
import { ElOverlay } from "../../overlay/index.mjs";
import { Loading as loading_default } from "../../../../../@element-plus/icons-vue/dist/index.mjs";
import { defineComponent, computed, ref, reactive, markRaw, watch, nextTick, onMounted, onBeforeUnmount, toRefs } from "vue";
var index_vue_vue_type_script_lang_default = defineComponent({
  name: "ElMessageBox",
  directives: { TrapFocus },
  components: {
    ElButton,
    ElFocusTrap: focus_trap_default$1,
    ElInput,
    ElOverlay,
    ElIcon,
    ...TypeComponents
  },
  inheritAttrs: false,
  props: {
    buttonSize: {
      type: String,
      validator: isValidComponentSize
    },
    modal: {
      type: Boolean,
      default: true
    },
    lockScroll: {
      type: Boolean,
      default: true
    },
    showClose: {
      type: Boolean,
      default: true
    },
    closeOnClickModal: {
      type: Boolean,
      default: true
    },
    closeOnPressEscape: {
      type: Boolean,
      default: true
    },
    closeOnHashChange: {
      type: Boolean,
      default: true
    },
    center: Boolean,
    draggable: Boolean,
    overflow: Boolean,
    roundButton: Boolean,
    container: {
      type: String,
      default: "body"
    },
    boxType: {
      type: String,
      default: ""
    }
  },
  emits: ["vanish", "action"],
  setup(props, { emit }) {
    const { locale, zIndex, ns, size: btnSize } = useGlobalComponentSettings("message-box", computed(() => props.buttonSize));
    const { t } = locale;
    const { nextZIndex } = zIndex;
    const visible = ref(false);
    const state = reactive({
      autofocus: true,
      beforeClose: null,
      callback: null,
      cancelButtonText: "",
      cancelButtonClass: "",
      confirmButtonText: "",
      confirmButtonClass: "",
      cancelButtonType: "",
      confirmButtonType: "primary",
      customClass: "",
      customStyle: {},
      dangerouslyUseHTMLString: false,
      distinguishCancelAndClose: false,
      icon: "",
      closeIcon: "",
      inputPattern: null,
      inputPlaceholder: "",
      inputType: "text",
      inputValue: "",
      inputValidator: void 0,
      inputErrorMessage: "",
      message: "",
      modalFade: true,
      modalClass: "",
      showCancelButton: false,
      showConfirmButton: true,
      type: "",
      title: void 0,
      showInput: false,
      action: "",
      confirmButtonLoading: false,
      cancelButtonLoading: false,
      confirmButtonLoadingIcon: markRaw(loading_default),
      cancelButtonLoadingIcon: markRaw(loading_default),
      confirmButtonDisabled: false,
      editorErrorMessage: "",
      validateError: false,
      zIndex: nextZIndex()
    });
    const typeClass = computed(() => {
      const type = state.type;
      return { [ns.bm("icon", type)]: type && TypeComponentsMap[type] };
    });
    const contentId = useId();
    const inputId = useId();
    const iconComponent = computed(() => {
      const type = state.type;
      return state.icon || type && TypeComponentsMap[type] || "";
    });
    const hasMessage = computed(() => !!state.message);
    const rootRef = ref();
    const headerRef = ref();
    const focusStartRef = ref();
    const inputRef = ref();
    const confirmRef = ref();
    const confirmButtonClasses = computed(() => state.confirmButtonClass);
    watch(() => state.inputValue, async (val) => {
      await nextTick();
      if (props.boxType === "prompt" && val) validate();
    }, { immediate: true });
    watch(() => visible.value, (val) => {
      var _a;
      if (val) {
        if (props.boxType !== "prompt") if (state.autofocus) focusStartRef.value = ((_a = confirmRef.value) == null ? void 0 : _a.$el) ?? rootRef.value;
        else focusStartRef.value = rootRef.value;
        state.zIndex = nextZIndex();
      }
      if (props.boxType !== "prompt") return;
      if (val) nextTick().then(() => {
        if (inputRef.value && inputRef.value.$el) if (state.autofocus) focusStartRef.value = getInputElement() ?? rootRef.value;
        else focusStartRef.value = rootRef.value;
      });
      else {
        state.editorErrorMessage = "";
        state.validateError = false;
      }
    });
    const { isDragging } = useDraggable(rootRef, headerRef, computed(() => props.draggable), computed(() => props.overflow));
    onMounted(async () => {
      await nextTick();
      if (props.closeOnHashChange) window.addEventListener("hashchange", doClose);
    });
    onBeforeUnmount(() => {
      if (props.closeOnHashChange) window.removeEventListener("hashchange", doClose);
    });
    function doClose() {
      if (!visible.value) return;
      visible.value = false;
      nextTick(() => {
        if (state.action) emit("action", state.action);
      });
    }
    const handleWrapperClick = () => {
      if (props.closeOnClickModal) handleAction(state.distinguishCancelAndClose ? "close" : "cancel");
    };
    const overlayEvent = useSameTarget(handleWrapperClick);
    const handleInputEnter = (e) => {
      var _a;
      if (state.inputType !== "textarea" && !((_a = inputRef.value) == null ? void 0 : _a.isComposing)) {
        e.preventDefault();
        return handleAction("confirm");
      }
    };
    const handleAction = (action) => {
      var _a;
      if (props.boxType === "prompt" && action === "confirm" && !validate()) return;
      state.action = action;
      if (state.beforeClose) (_a = state.beforeClose) == null ? void 0 : _a.call(state, action, state, doClose);
      else doClose();
    };
    const validate = () => {
      if (props.boxType === "prompt") {
        const inputPattern = state.inputPattern;
        if (inputPattern && !inputPattern.test(state.inputValue || "")) {
          state.editorErrorMessage = state.inputErrorMessage || t("el.messagebox.error");
          state.validateError = true;
          return false;
        }
        const inputValidator = state.inputValidator;
        if (isFunction(inputValidator)) {
          const validateResult = inputValidator(state.inputValue);
          if (validateResult === false) {
            state.editorErrorMessage = state.inputErrorMessage || t("el.messagebox.error");
            state.validateError = true;
            return false;
          }
          if (isString(validateResult)) {
            state.editorErrorMessage = validateResult;
            state.validateError = true;
            return false;
          }
        }
      }
      state.editorErrorMessage = "";
      state.validateError = false;
      return true;
    };
    const getInputElement = () => {
      var _a;
      const inputRefs = (_a = inputRef.value) == null ? void 0 : _a.$refs;
      return (inputRefs == null ? void 0 : inputRefs.input) ?? (inputRefs == null ? void 0 : inputRefs.textarea);
    };
    const handleClose = () => {
      handleAction("close");
    };
    const onCloseRequested = () => {
      if (props.closeOnPressEscape) handleClose();
    };
    if (props.lockScroll) useLockscreen(visible, { ns });
    return {
      ...toRefs(state),
      ns,
      overlayEvent,
      visible,
      hasMessage,
      typeClass,
      contentId,
      inputId,
      btnSize,
      iconComponent,
      confirmButtonClasses,
      rootRef,
      focusStartRef,
      headerRef,
      inputRef,
      isDragging,
      confirmRef,
      doClose,
      handleClose,
      onCloseRequested,
      handleWrapperClick,
      handleInputEnter,
      handleAction,
      t
    };
  }
});
export {
  index_vue_vue_type_script_lang_default as default
};
