( function () {
	'use strict';

	var config = window.rsmsparkRsf || {};
	var respectReduced =
		typeof config.respectReducedMotion === 'undefined'
			? true
			: !! config.respectReducedMotion;

	function prefersReducedMotion() {
		return (
			respectReduced &&
			window.matchMedia &&
			window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches
		);
	}

	function reveal( el, overrides ) {
		if ( el.classList.contains( 'is-rsm-rsf-visible' ) ) {
			return;
		}

		overrides = overrides || {};
		var duration = parseInt(
			overrides.duration ||
				el.getAttribute( 'data-rsm-animation-duration' ) ||
				'600',
			10
		);
		var delay = parseInt(
			overrides.delay || el.getAttribute( 'data-rsm-animation-delay' ) || '0',
			10
		);
		var easing =
			overrides.easing ||
			el.getAttribute( 'data-rsm-animation-easing' ) ||
			'ease-out';

		if ( prefersReducedMotion() ) {
			el.classList.add( 'is-rsm-rsf-visible' );
			return;
		}

		el.style.transitionProperty = 'opacity, transform';
		el.style.transitionDuration = Math.max( 0, duration ) + 'ms';
		el.style.transitionDelay = Math.max( 0, delay ) + 'ms';
		el.style.transitionTimingFunction = easing;

		window.requestAnimationFrame( function () {
			window.requestAnimationFrame( function () {
				el.classList.add( 'is-rsm-rsf-visible' );
			} );
		} );
	}

	function getStaggerChildren( host ) {
		var inner = host.querySelector( ':scope > .wp-block-group__inner-container' );
		var container = inner || host;

		// Stagger direct child blocks — includes core blocks, sections, and RSM widgets.
		return container.querySelectorAll( ':scope > *' );
	}

	function hydrateAnimationTargets( scope ) {
		scope.querySelectorAll( '.rsm-rsf-animate' ).forEach( function ( el ) {
			if ( el.hasAttribute( 'data-rsm-animation' ) ) {
				return;
			}

			var match = el.className.match( /\brsm-rsf-animate--([a-z0-9-]+)\b/ );
			if ( ! match ) {
				return;
			}

			el.setAttribute( 'data-rsm-animation', match[ 1 ] );
			if ( ! el.hasAttribute( 'data-rsm-animation-duration' ) ) {
				el.setAttribute( 'data-rsm-animation-duration', '600' );
			}
			if ( ! el.hasAttribute( 'data-rsm-animation-easing' ) ) {
				el.setAttribute( 'data-rsm-animation-easing', 'ease-out' );
			}
		} );
	}

	function staggerChildren( host ) {
		if ( host.hasAttribute( 'data-rsm-stagger-done' ) ) {
			return;
		}

		host.setAttribute( 'data-rsm-stagger-done', '1' );

		var stagger = parseInt( host.getAttribute( 'data-rsm-stagger' ) || '0', 10 );
		if ( stagger <= 0 ) {
			return;
		}

		var animation = host.getAttribute( 'data-rsm-stagger-animation' ) || 'fade';
		var duration = host.getAttribute( 'data-rsm-stagger-duration' ) || '600';
		var baseDelay = parseInt(
			host.getAttribute( 'data-rsm-stagger-delay' ) || '0',
			10
		);
		var easing = host.getAttribute( 'data-rsm-stagger-easing' ) || 'ease-out';

		var children = getStaggerChildren( host );

		if ( ! children.length ) {
			host.removeAttribute( 'data-rsm-stagger-done' );
			return;
		}

		children.forEach( function ( child, index ) {
			child.classList.add( 'rsmspark-rsf-animate', 'rsmspark-rsf-animate--' + animation );
			void child.offsetWidth;
			reveal( child, {
				duration: duration,
				delay: baseDelay + index * stagger,
				easing: easing,
			} );
		} );
	}

	function observeNodes( scope, observer ) {
		scope.querySelectorAll( '[data-rsm-animation]' ).forEach( function ( el ) {
			observer.observe( el );
		} );

		scope.querySelectorAll( '[data-rsm-stagger]' ).forEach( function ( host ) {
			observer.observe( host );
		} );
	}

	function init( root ) {
		var scope = root && root.querySelectorAll ? root : document;

		hydrateAnimationTargets( scope );

		var animated = scope.querySelectorAll(
			'[data-rsm-animation], [data-rsm-stagger]'
		);

		if ( ! animated.length ) {
			return;
		}

		if ( prefersReducedMotion() || ! ( 'IntersectionObserver' in window ) ) {
			animated.forEach( function ( el ) {
				if ( el.hasAttribute( 'data-rsm-stagger' ) ) {
					staggerChildren( el );
				} else {
					el.classList.add( 'is-rsm-rsf-visible' );
				}
			} );
			return;
		}

		var observer = new IntersectionObserver(
			function ( entries ) {
				entries.forEach( function ( entry ) {
					if ( ! entry.isIntersecting ) {
						return;
					}

					var target = entry.target;

					if ( target.hasAttribute( 'data-rsm-stagger' ) ) {
						staggerChildren( target );
					} else {
						reveal( target );
					}

					observer.unobserve( target );
				} );
			},
			{ root: null, rootMargin: '0px', threshold: 0.05 }
		);

		observeNodes( scope, observer );

		// IntersectionObserver can miss above-the-fold nodes on first paint.
		animated.forEach( function ( el ) {
			var rect = el.getBoundingClientRect();
			if ( rect.top >= window.innerHeight || rect.bottom <= 0 ) {
				return;
			}

			if ( el.hasAttribute( 'data-rsm-stagger' ) ) {
				staggerChildren( el );
			} else {
				reveal( el );
			}

			observer.unobserve( el );
		} );
	}

	window.rsmRsfInitAnimations = init;

	if ( document.readyState === 'loading' ) {
		document.addEventListener( 'DOMContentLoaded', function () {
			init( document );
		} );
	} else {
		init( document );
	}
} )();
