import { useBaseConfig } from "../config-provider/context.js";
import config_provider_default, { globalConfig } from "../config-provider/index.js";
import { useAppConfig } from "../app/context.js";
import PurePanel_default from "./PurePanel.js";
import PureList_default from "./PureList.js";
import useNotification, { useInternalNotification } from "./useNotification.js";
import { createVNode, defineComponent, getCurrentInstance, isVNode, onMounted, render, shallowRef, watch } from "vue";

//#region src/notification/index.tsx
function _isSlot(s) {
	return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
}
let notification = null;
let taskQueue = [];
let defaultGlobalConfig = {};
let act = (callback) => callback();
function getGlobalContext() {
	const { getContainer, rtl, maxCount, top, bottom, showProgress, pauseOnHover } = defaultGlobalConfig;
	const mergedContainer = getContainer?.() || document.body;
	let appContext = defaultGlobalConfig.appContext;
	const instance = getCurrentInstance();
	if (instance && !appContext) appContext = instance.appContext;
	else if (!appContext) appContext = globalConfig().appContext;
	return {
		getContainer: () => mergedContainer,
		rtl,
		maxCount,
		top,
		bottom,
		showProgress,
		pauseOnHover,
		appContext
	};
}
const GlobalHolder = /* @__PURE__ */ defineComponent((props, { expose }) => {
	const { notificationConfig, sync } = props;
	const { getPrefixCls } = useBaseConfig();
	const prefixCls = defaultGlobalConfig?.prefixCls || getPrefixCls("notification");
	const appConfig = useAppConfig();
	const [api, holder] = useInternalNotification({
		...notificationConfig,
		prefixCls,
		...appConfig.notification || {}
	});
	onMounted(() => {
		sync?.();
	});
	const instance = { ...api };
	Object.keys(instance).forEach((method) => {
		instance[method] = (...args) => {
			sync();
			return api[method](...args);
		};
	});
	expose({
		instance,
		sync
	});
	return () => {
		if (typeof holder === "function") return holder?.();
		return holder;
	};
}, { props: {
	notificationConfig: { required: true },
	sync: {
		type: Function,
		required: true
	}
} });
const GlobalHolderWrapper = /* @__PURE__ */ defineComponent((props) => {
	const notificationConfig = shallowRef(getGlobalContext());
	const holderRef = shallowRef();
	const sync = () => {
		notificationConfig.value = getGlobalContext();
	};
	onMounted(sync);
	let filled = false;
	watch(() => holderRef.value, (holder) => {
		if (holder && !filled) {
			filled = true;
			props.onReady?.({
				instance: holder.instance,
				sync
			});
		}
	}, { immediate: true });
	const global = globalConfig();
	return () => {
		const holderNode = createVNode(GlobalHolder, {
			"ref": holderRef,
			"sync": sync,
			"notificationConfig": notificationConfig.value
		}, null);
		const configHolderNode = createVNode(config_provider_default, {
			"prefixCls": global.getRootPrefixCls(),
			"iconPrefixCls": global.getIconPrefixCls(),
			"theme": global.theme.value
		}, _isSlot(holderNode) ? holderNode : { default: () => [holderNode] });
		return global.holderRender ? global.holderRender(configHolderNode) : configHolderNode;
	};
}, { props: { onReady: {
	type: Function,
	required: false
} } });
function flushNotificationQueue() {
	if (!notification) {
		const holderFragment = document.createDocumentFragment();
		const newNotification = { fragment: holderFragment };
		notification = newNotification;
		act(() => {
			const vnode = createVNode(GlobalHolderWrapper, { onReady: (node) => {
				Promise.resolve().then(() => {
					if (!newNotification.instance && node?.instance) {
						newNotification.instance = node.instance;
						newNotification.sync = node.sync;
						flushNotificationQueue();
					}
				});
			} });
			const globalCtx = getGlobalContext();
			if (globalCtx.appContext) vnode.appContext = globalCtx.appContext;
			render(vnode, holderFragment);
		});
		return;
	}
	if (!notification.instance) return;
	taskQueue.forEach((task) => {
		switch (task.type) {
			case "open":
				act(() => {
					notification?.instance?.open({
						...defaultGlobalConfig,
						...task.config
					});
				});
				break;
			case "destroy":
				act(() => {
					notification?.instance?.destroy(task.key);
				});
				break;
		}
	});
	taskQueue = [];
}
function setNotificationGlobalConfig(config) {
	defaultGlobalConfig = {
		...defaultGlobalConfig,
		...config
	};
	act(() => {
		notification?.sync?.();
	});
}
function open(config) {
	taskQueue.push({
		type: "open",
		config
	});
	flushNotificationQueue();
}
function destroy(key) {
	taskQueue.push({
		type: "destroy",
		key
	});
	flushNotificationQueue();
}
const methods = [
	"success",
	"info",
	"warning",
	"error"
];
const staticMethods = {
	open,
	destroy,
	config: setNotificationGlobalConfig,
	useNotification,
	_InternalPanelDoNotUseOrYouWillBeFired: PurePanel_default,
	_InternalListDoNotUseOrYouWillBeFired: PureList_default
};
methods.forEach((type) => {
	staticMethods[type] = (config) => open({
		...config,
		type
	});
});
function noop() {}
let _actWrapper = noop;
if (process.env.NODE_ENV === "test") _actWrapper = (wrapper) => {
	act = wrapper;
};
const actWrapper = _actWrapper;
let _actDestroy = noop;
if (process.env.NODE_ENV === "test") _actDestroy = () => {
	notification = null;
	taskQueue = [];
};
const actDestroy = _actDestroy;
var notification_default = staticMethods;

//#endregion
export { actDestroy, actWrapper, notification_default as default, useNotification };