/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-e694c50 | Cube Dev Team */
import { useEvent } from "../../../_internal/hooks/use-event.js";
import { ItemAction } from "../../actions/ItemAction/ItemAction.js";
import { useToastContext } from "../Notifications/NotificationContext.js";
import { useEffect, useRef } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";

//#region src/components/overlays/Toast/useProgressToast.tsx
const RESULT_DURATION = 3e3;
/**
* Check if the options represent an "empty" value (null, undefined, false, or empty object).
* When empty, the hook should immediately remove any existing toast.
*/
function isEmptyOptions(options) {
	if (options == null || options === false) return true;
	if (typeof options === "object" && Object.keys(options).length === 0) return true;
	return false;
}
function getStringValue(value) {
	return typeof value === "string" ? value : void 0;
}
/**
* Hook to display a progress toast that persists while loading.
*
* @example
* ```tsx
* useProgressToast(
*   isLoading
*     ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }
*     : { isLoading: false, title: 'Saved!', icon: <IconCheck />, theme: 'success' }
* );
*
* // Or with error handling:
* useProgressToast(
*   isLoading
*     ? { isLoading: true, title: 'Saving...', icon: <Spinner /> }
*     : isError
*       ? { isLoading: false, title: 'Error', description: errorMessage, theme: 'danger' }
*       : { isLoading: false, title: 'Saved!', theme: 'success' }
* );
*
* // Pass empty value to immediately remove any existing toast:
* useProgressToast(shouldShow ? { isLoading: true, title: 'Loading...' } : null);
*
* // Or call with no argument to dismiss:
* useProgressToast();
* ```
*/
function useProgressToast(options) {
	const { addToast, removeToast, updateToast } = useToastContext();
	const toastIdRef = useRef(null);
	const wasLoadingRef = useRef(null);
	const hideTimerRef = useRef(null);
	const isFirstRenderRef = useRef(true);
	const optionsRef = useRef(options);
	const hasBeenLoadingRef = useRef(false);
	const hiddenByUserRef = useRef(false);
	const prevThemeRef = useRef(void 0);
	const prevTitleRef = useRef(void 0);
	const prevDescriptionRef = useRef(void 0);
	optionsRef.current = options;
	const clearHideTimer = () => {
		if (hideTimerRef.current) {
			clearTimeout(hideTimerRef.current);
			hideTimerRef.current = null;
		}
	};
	const isEmpty = isEmptyOptions(options);
	const isLoading = isEmpty ? false : options.isLoading;
	const isDismissable = isEmpty ? false : !!options.isDismissable;
	const currentTheme = isEmpty ? void 0 : options.theme;
	const currentTitle = isEmpty ? void 0 : getStringValue(options.title);
	const currentDescription = isEmpty ? void 0 : getStringValue(options.description);
	const handleHide = useEvent(() => {
		if (toastIdRef.current != null) {
			removeToast(toastIdRef.current);
			toastIdRef.current = null;
		}
		hiddenByUserRef.current = true;
	});
	useEffect(() => {
		const wasLoading = wasLoadingRef.current;
		const isFirstRender = isFirstRenderRef.current;
		const currentOptions = optionsRef.current;
		if (isEmptyOptions(currentOptions)) {
			clearHideTimer();
			if (toastIdRef.current != null) {
				removeToast(toastIdRef.current);
				toastIdRef.current = null;
			}
			hasBeenLoadingRef.current = false;
			hiddenByUserRef.current = false;
			wasLoadingRef.current = null;
			isFirstRenderRef.current = false;
			prevThemeRef.current = void 0;
			prevTitleRef.current = void 0;
			prevDescriptionRef.current = void 0;
			return;
		}
		const { isLoading: currentIsLoading, isDismissable: _isDismissable, ...currentToastData } = currentOptions;
		const themeChanged = currentTheme !== prevThemeRef.current;
		const titleChanged = currentTitle !== prevTitleRef.current;
		const descriptionChanged = currentDescription !== prevDescriptionRef.current;
		const dataChanged = themeChanged || titleChanged || descriptionChanged;
		const hideAction = isDismissable && currentIsLoading ? /* @__PURE__ */ jsx(ItemAction, {
			type: "secondary",
			onPress: handleHide,
			children: "Hide"
		}) : null;
		const mergedActions = hideAction ? /* @__PURE__ */ jsxs(Fragment$1, { children: [currentToastData.actions, hideAction] }) : currentToastData.actions;
		const toastData = {
			title: void 0,
			description: void 0,
			theme: void 0,
			icon: void 0,
			itemProps: void 0,
			...currentToastData,
			actions: mergedActions,
			isLoading: currentIsLoading,
			duration: null
		};
		const showToast = () => {
			if (toastIdRef.current != null) updateToast(toastIdRef.current, toastData);
			else toastIdRef.current = addToast(toastData, true);
		};
		const showToastWithTimer = () => {
			showToast();
			hideTimerRef.current = setTimeout(() => {
				if (toastIdRef.current != null) {
					removeToast(toastIdRef.current);
					toastIdRef.current = null;
				}
			}, RESULT_DURATION);
		};
		if (currentIsLoading) {
			hasBeenLoadingRef.current = true;
			clearHideTimer();
			if (hiddenByUserRef.current) {} else if (toastIdRef.current == null) showToast();
			else if (dataChanged) showToast();
		} else if (wasLoading === true && !currentIsLoading) {
			hiddenByUserRef.current = false;
			clearHideTimer();
			if (currentTitle) showToastWithTimer();
			else if (toastIdRef.current != null) {
				removeToast(toastIdRef.current);
				toastIdRef.current = null;
			}
		} else if (!currentIsLoading && !isFirstRender && hasBeenLoadingRef.current && dataChanged && toastIdRef.current != null) if (currentTitle) {
			clearHideTimer();
			showToastWithTimer();
		} else {
			clearHideTimer();
			removeToast(toastIdRef.current);
			toastIdRef.current = null;
		}
		wasLoadingRef.current = currentIsLoading;
		isFirstRenderRef.current = false;
		prevThemeRef.current = currentTheme;
		prevTitleRef.current = currentTitle;
		prevDescriptionRef.current = currentDescription;
	}, [
		isEmpty,
		isLoading,
		isDismissable,
		currentTheme,
		currentTitle,
		currentDescription,
		addToast,
		removeToast,
		updateToast,
		handleHide
	]);
	useEffect(() => {
		return () => {
			clearHideTimer();
			if (toastIdRef.current != null) {
				removeToast(toastIdRef.current);
				toastIdRef.current = null;
			}
		};
	}, [removeToast]);
}

//#endregion
export { useProgressToast };
//# sourceMappingURL=useProgressToast.js.map