/**
 * Snackbar React Component that is fixed in the bottom right corner of the screen when rendered.
 * Has children that can be passed in to display the content of the Snackbar.
 *
 * @param {Object} props - Component props.
 * @param {string} props.className - Additional classes to add to the Snackbar.
 * @param {string} props.children - Content to display in the Snackbar.
 * @param {string} props.variant - Variant of the Snackbar.
 * @param {string} props.position - Position of the Snackbar.
 * @param {string} props.duration - Duration of the Snackbar.
 * @param {string} props.onClose - Function to call when the Snackbar is closed.
 * @returns {React.Component} - Snackbar React Component.
 * @example
 * <Snackbar
 * 	className="my-snackbar"
 * 	variant="success"
 * 	position="bottom-right"
 * 	duration="5000"
 * 	onClose={() => console.log('Snackbar closed')}
 * >
 */

import {useCallback, useEffect, useRef} from "react";
import {TbCircleX} from "react-icons/tb";

// If there are multiple snackbars,
// slide them up in the order of DOM,
// one on top of the other with a 15px gap between,
// and take into account the height of the snackbar and wpfooter (WP footer ID).
function reArrangeSnackbars() {
	const snackbars = document.querySelectorAll('.dxp-snackbar');
	snackbars.forEach(function (snackbar, index) {
		snackbar.style.bottom = "".concat((wpfooter.offsetHeight + 40) + (snackbar.offsetHeight + 15) * index, "px");
	});
}

export default function Snackbar(
	{
		show,
		className = '',
		children,
		variant = 'default',
		position = 'bottom-right',
		duration = 5000,
		showCloseIcon = true,
		onClose = null,
	}
) {
	const classes = VARIANTS[variant || 'default'] + ' ' + POSITIONS[position || 'bottom-right'];
	const snackbarRef = useRef(null);
	const timeoutRef = useRef(null);

	// On render, slide in the snackbar.
	useEffect(function () {
		if (show) {
			snackbarRef.current.classList.remove('dxp-translate-y-full');
			snackbarRef.current.classList.add('dxp-translate-y-0');
			snackbarRef.current.classList.add('dxp-opacity-100');
		}
	});

	const close = useCallback(function () {
		// Slide out the snackbar.
		snackbarRef.current.classList.remove('dxp-translate-y-0');
		snackbarRef.current.classList.remove('dxp-opacity-100');
		snackbarRef.current.classList.add('dxp-translate-y-full');

		// Remove the snackbar from the DOM.
		document.addEventListener('animationend', function (event) {
			snackbarRef.current.remove();
		});

		// Call the onClose function.
		if (typeof onClose === 'function') {
			onClose();
		}

		// After the snackbar is removed, slide up the remaining snackbars.
		reArrangeSnackbars();
	}, [onClose]);

	useEffect(function () {
		reArrangeSnackbars();

		// If the user clicks on the snackbar close icon, close it.
		if (showCloseIcon) {
			snackbarRef.current.addEventListener('click', function (event) {
				if (event.target.classList.contains('dxp-snackbar--close')) {
					close();
				}
			});
		}

		// If the show prop changes to false, close the snackbar.
		if (!show) {
			close();
		}

		// If the duration is 0, don't close the snackbar.
		if (duration === 0) {
			return;
		}

		timeoutRef.current = setTimeout(close, duration);
		return function () {
			clearTimeout(timeoutRef.current);
		};
	}, [show, duration]);

	return (
		<div className={"dxp-snackbar".concat(classes, " ").concat(className)} ref={snackbarRef}>
			{children}
			{showCloseIcon && (
				<TbCircleX
					size="20"
					className="dxp-snackbar--close dxp-absolute dxp-top-2 dxp-right-2 dxp-cursor-pointer"
					onClick={close}
				/>
			)}
		</div>
	);
};

const VARIANTS = {
	default: `
		dxp-bg-tundora
		dxp-text-white
		dxp-fixed
		dxp-py-2
		dxp-pl-4
		dxp-pr-8
		dxp-rounded-sm
		dxp-shadow-md
		dxp-text-sm
		dxp-transform
		dxp-transition
		dxp-ease-in-out
		dxp-duration-500
		sm:dxp-duration-700
		dxp-pointer-events-auto
		dxp-translate-y-full
		dxp-opacity-0
	`,
}

const POSITIONS = {
	"bottom-right": `
		dxp-bottom-28
	`,
}
