import React, {useCallback, useMemo} from "react";
import {ErrorBoundary, ErrorBoundaryProps} from "react-error-boundary";
import {useNotify} from "../Notifications/Notifications";
import {Notification, NotificationType} from "../Notifications/Notification";

/**
 * A React error boundary that show errors in notifications.
 */
export function NotifyErrorsBoundary({children, onError, fallback, fallbackRender, FallbackComponent, ...props}: React.PropsWithChildren<Partial<ErrorBoundaryProps>>)
{
	// Get notification function.
	const notify = useNotify();

	/**
	 * Error handling function.
	 */
	const handleError = useCallback((error: Error, info: React.ErrorInfo) => {
		// Show a notification about the error.
		notify(<Notification type={NotificationType.ERROR}>Unexpected error: {error.message}</Notification>);
		// Then call defined onError, if there is one.
		onError?.(error, info);
	}, [onError]);

	// Define default fallback component.
	const defaultFallback = useMemo(() => <></>, []);

	if (!fallback && !fallbackRender && !FallbackComponent)
		// Set default fallback if nothing is set.
		fallback = defaultFallback;

	return (
		<ErrorBoundary onError={handleError} fallback={fallback} {...props}>
			{children}
		</ErrorBoundary>
	);
}
