/**
 * DSM Animated Headline Class for Divi 5
 * Handles animated headline functionality
 */
class DSMAnimatedHeadline {
	constructor( element ) {
		this.element = element;
		this.dataset = this.parseDataset();
		this.isInitialized = false;
		this.animationTimeouts = [];
		this.init();
	}

	/**
	 * Parse dataset from element
	 */
	parseDataset() {
		try {
			if ( this.element.dataset.dsmAnimatedHeadlineOptions ) {
				return JSON.parse(
					this.element.dataset.dsmAnimatedHeadlineOptions
				);
			}

			const optionsElement = this.element.querySelector(
				'[data-dsm-animated-headline-options]'
			);
			if ( optionsElement ) {
				return JSON.parse(
					optionsElement.dataset.dsmAnimatedHeadlineOptions
				);
			}
		} catch ( e ) {
			console.warn( 'Failed to parse animated headline options:', e );
		}
		return {};
	}

	/**
	 * Initialize the animated headline
	 */
	init() {
		if ( this.isInitialized ) {
			this.destroy();
		}

		if ( ! this.element.classList.contains( 'dsm-headline' ) ) {
			this.element.classList.add( 'dsm-headline' );
		}

		const effect = this.dataset.effect || 'rotate-1';
		this.element.classList.add( effect );

		const letterEffects = [ 'scale', 'type', 'rotate-2', 'rotate-3' ];
		if ( letterEffects.includes( effect ) ) {
			this.element.classList.add( 'dsm-headline-letters' );
		}

		if ( this.element.classList.contains( 'dsm-headline-letters' ) ) {
			this.singleLetters( this.element.querySelectorAll( 'b' ) );
		}

		this.isInitialized = true;
		this.animateHeadline();

		const timeout = setTimeout( () => {
			this.element.classList.add( 'dsm-headline--is-animating' );
		}, 100 );
		this.animationTimeouts.push( timeout );
	}

	/**
	 * Destroy and reset the headline
	 */
	destroy() {
		this.isInitialized = false;

		this.animationTimeouts.forEach( ( timeout ) =>
			clearTimeout( timeout )
		);
		this.animationTimeouts = [];

		const words = this.element.querySelectorAll( 'b' );
		words.forEach( ( word ) => {
			word.classList.remove( 'is-visible', 'is-hidden' );
			if ( word === words[ 0 ] ) {
				word.classList.add( 'is-visible' );
			} else {
				word.classList.add( 'is-hidden' );
			}
		} );
	}

	/**
	 * Process single letters for letter-based animations
	 */
	singleLetters( words ) {
		if ( ! words.length ) return;

		words.forEach( ( word ) => {
			const letters = word.textContent.split( '' );
			const selected = word.classList.contains( 'is-visible' );
			const newLetters = letters
				.map( ( letter ) => {
					if ( this.element.classList.contains( 'rotate-2' ) ) {
						letter = `<em>${ letter }</em>`;
					}
					return selected
						? `<i class="in">${ letter }</i>`
						: `<i>${ letter }</i>`;
				} )
				.join( '' );
			word.innerHTML = newLetters;
			word.style.opacity = 1;
		} );
	}

	/**
	 * Start the headline animation
	 */
	animateHeadline() {
		const effect = this.dataset.effect || 'rotate-1';
		const animationDelay = this.dataset.animationDelay || 2500;
		const wordsWrapper = this.element.querySelector(
			'.dsm-animated-words-wrapper'
		);

		if ( ! wordsWrapper ) return;

		if ( effect === 'loading-bar' ) {
			this.setupLoadingBar( wordsWrapper );
		} else if ( effect === 'clip' ) {
			this.setupClipEffect( wordsWrapper );
		} else if ( effect !== 'type' ) {
			this.setupStandardWidth( wordsWrapper );
		}

		const visibleWord = this.element.querySelector( '.is-visible' );
		if ( visibleWord ) {
			const timeout = setTimeout( () => {
				this.hideWord( visibleWord );
			}, animationDelay );
			this.animationTimeouts.push( timeout );
		}
	}

	/**
	 * Setup loading bar effect
	 */
	setupLoadingBar( wordsWrapper ) {
		const barAnimationDelay = 3800;
		const barWaiting = barAnimationDelay - 3000;

		const timeout = setTimeout( () => {
			wordsWrapper.classList.add( 'is-loading' );
		}, barWaiting );
		this.animationTimeouts.push( timeout );
	}

	/**
	 * Setup clip effect
	 */
	setupClipEffect( wordsWrapper ) {
		const visibleWord = this.element.querySelector( '.is-visible' );
		if ( visibleWord ) {
			const newWidth = visibleWord.offsetWidth + 10;
			console.log( 'New Width', newWidth );
			wordsWrapper.style.width = `${ newWidth }px`;
		}
	}

	/**
	 * Setup standard width for other effects
	 */
	setupStandardWidth( wordsWrapper ) {
		const words = wordsWrapper.querySelectorAll( 'b' );
		let width = 0;
		words.forEach( ( word ) => {
			const wordWidth = word.offsetWidth;
			if ( wordWidth > width ) width = wordWidth;
		} );
		console.log( 'width', width );
		wordsWrapper.style.width = `${ width + 10 }px`;
	}

	/**
	 * Hide current word and show next
	 */
	hideWord( word ) {
		if ( ! word ) return;

		const nextWord = this.takeNext( word );
		const effect = this.dataset.effect || 'rotate-1';

		// Set wrapper width to the next word's width for effects like rotate, push, slide, scale, zoom
		if (
			[
				'rotate-1',
				'rotate-2',
				'rotate-3',
				'slide',
				'zoom',
				'scale',
				'push',
			].includes( effect )
		) {
			const wrapper = this.element.querySelector(
				'.dsm-animated-words-wrapper'
			);
			if ( wrapper && nextWord ) {
				wrapper.style.transition = 'width 0.2s'; // Smooth transition for width change
				wrapper.style.width = `${ nextWord.offsetWidth + 10 }px`;
			}
		}

		if ( effect === 'type' ) {
			this.handleTypeEffect( word, nextWord );
		} else if (
			this.element.classList.contains( 'dsm-headline-letters' )
		) {
			this.handleLettersEffect( word, nextWord );
		} else if ( effect === 'clip' ) {
			this.handleClipEffect( word, nextWord );
		} else if ( effect === 'loading-bar' ) {
			this.handleLoadingBarEffect( word, nextWord );
		} else {
			this.handleStandardEffect( word, nextWord );
		}
	}

	/**
	 * Handle type effect
	 */
	handleTypeEffect( word, nextWord ) {
		const parentSpan = word.parentElement;
		if ( ! parentSpan ) return;

		const selectionDuration = this.dataset.typeSelectionDuration || 500;
		const typeAnimationDelay = selectionDuration + 800;
		const typeLettersDelay = this.dataset.typeLettersDelay || 150;

		parentSpan.classList.add( 'selected' );
		parentSpan.classList.remove( 'waiting' );

		const timeout1 = setTimeout( () => {
			parentSpan.classList.remove( 'selected' );
			word.classList.remove( 'is-visible' );
			word.classList.add( 'is-hidden' );
			const letters = word.querySelectorAll( 'i' );
			letters.forEach( ( letter ) => {
				letter.classList.remove( 'in' );
				letter.classList.add( 'out' );
			} );
		}, selectionDuration );
		this.animationTimeouts.push( timeout1 );

		const timeout2 = setTimeout( () => {
			this.showWord( nextWord, typeLettersDelay );
		}, typeAnimationDelay );
		this.animationTimeouts.push( timeout2 );
	}

	/**
	 * Handle letters effect
	 */
	handleLettersEffect( word, nextWord ) {
		const lettersDelay = this.dataset.lettersDelay || 50;
		const animationDelay = this.dataset.animationDelay || 2500;
		const bool =
			word.querySelectorAll( 'i' ).length >=
			nextWord.querySelectorAll( 'i' ).length;

		this.hideLetter( word.querySelector( 'i' ), word, bool, lettersDelay );
		this.showLetter(
			nextWord.querySelector( 'i' ),
			nextWord,
			bool,
			lettersDelay
		);
	}

	/**
	 * Handle clip effect
	 */
	handleClipEffect( word, nextWord ) {
		const wrapper = this.element.querySelector(
			'.dsm-animated-words-wrapper'
		);
		const revealDuration = this.dataset.clipRevealDuration || 600;
		const revealAnimationDelay =
			this.dataset.clipRevealAnimationDelay || 1500;

		if ( wrapper ) {
			wrapper.style.transition = 'width 0.2s';
			wrapper.style.width = `${ word.offsetWidth + 10 }px`;

			const timeout1 = setTimeout( () => {
				wrapper.style.width = '2px';

				const timeout2 = setTimeout( () => {
					this.switchWord( word, nextWord );
					wrapper.style.width = `${ nextWord.offsetWidth + 10 }px`;
					this.showWord( nextWord );

					const timeout3 = setTimeout( () => {
						this.hideWord( nextWord );
					}, revealAnimationDelay );
					this.animationTimeouts.push( timeout3 );
				}, revealDuration );
				this.animationTimeouts.push( timeout2 );
			}, 50 );
			this.animationTimeouts.push( timeout1 );
		}
	}

	/**
	 * Handle loading bar effect
	 */
	handleLoadingBarEffect( word, nextWord ) {
		const wrapper = this.element.querySelector(
			'.dsm-animated-words-wrapper'
		);
		const barAnimationDelay = 3800;

		if ( wrapper ) {
			wrapper.classList.remove( 'is-loading' );
			this.switchWord( word, nextWord );

			const timeout1 = setTimeout( () => {
				wrapper.classList.add( 'is-loading' );
			}, 50 );
			this.animationTimeouts.push( timeout1 );

			const timeout2 = setTimeout( () => {
				this.hideWord( nextWord );
			}, barAnimationDelay );
			this.animationTimeouts.push( timeout2 );
		}
	}

	/**
	 * Handle standard effect
	 */
	handleStandardEffect( word, nextWord ) {
		const animationDelay = this.dataset.animationDelay || 2500;
		this.switchWord( word, nextWord );
		const timeout = setTimeout( () => {
			this.hideWord( nextWord );
		}, animationDelay );
		this.animationTimeouts.push( timeout );
	}

	/**
	 * Show word with animation
	 */
	showWord( word, duration ) {
		if ( ! word ) return;

		const effect = this.dataset.effect || 'rotate-1';

		if ( effect === 'type' ) {
			this.showLetter( word.querySelector( 'i' ), word, false, duration );
			word.classList.add( 'is-visible' );
			word.classList.remove( 'is-hidden' );
		} else if ( effect === 'clip' ) {
			word.classList.add( 'is-visible' );
			word.classList.remove( 'is-hidden' );
		}
	}

	/**
	 * Hide letter with animation
	 */
	hideLetter( letter, word, bool, duration ) {
		if ( ! letter ) return;

		const animationDelay = this.dataset.animationDelay || 2500;

		letter.classList.remove( 'in' );
		letter.classList.add( 'out' );

		if ( letter.nextElementSibling ) {
			const timeout = setTimeout( () => {
				this.hideLetter(
					letter.nextElementSibling,
					word,
					bool,
					duration
				);
			}, duration );
			this.animationTimeouts.push( timeout );
		} else if ( bool ) {
			const timeout = setTimeout( () => {
				this.hideWord( this.takeNext( word ) );
			}, animationDelay );
			this.animationTimeouts.push( timeout );
		}
	}

	/**
	 * Show letter with animation
	 */
	showLetter( letter, word, bool, duration ) {
		if ( ! letter ) return;

		const animationDelay = this.dataset.animationDelay || 2500;

		letter.classList.add( 'in' );
		letter.classList.remove( 'out' );

		if ( letter.nextElementSibling ) {
			const timeout = setTimeout( () => {
				this.showLetter(
					letter.nextElementSibling,
					word,
					bool,
					duration
				);
			}, duration );
			this.animationTimeouts.push( timeout );
		} else {
			const parent = word.closest( '.dsm-animated-headline' );
			if ( parent && parent.classList.contains( 'type' ) ) {
				const timeout1 = setTimeout( () => {
					const wrapper = parent.querySelector(
						'.dsm-animated-words-wrapper'
					);
					if ( wrapper ) {
						wrapper.classList.add( 'waiting' );
					}
				}, 200 );
				this.animationTimeouts.push( timeout1 );
			}
			if ( ! bool ) {
				const timeout2 = setTimeout( () => {
					this.hideWord( word );
				}, animationDelay );
				this.animationTimeouts.push( timeout2 );
			}
		}
	}

	/**
	 * Get next word in sequence
	 */
	takeNext( word ) {
		return word.nextElementSibling || word.parentElement.firstElementChild;
	}

	/**
	 * Switch between words
	 */
	switchWord( oldWord, newWord ) {
		if ( ! oldWord || ! newWord ) return;

		oldWord.classList.remove( 'is-visible' );
		oldWord.classList.add( 'is-hidden' );
		newWord.classList.remove( 'is-hidden' );
		newWord.classList.add( 'is-visible' );
	}
}

/**
 * Initialize animated headlines when DOM is ready
 */
document.addEventListener( 'DOMContentLoaded', () => {
	const animatedHeadlines = document.querySelectorAll(
		'[data-dsm-animated-headline-options]'
	);

	animatedHeadlines.forEach( ( headline ) => {
		const observer = new IntersectionObserver(
			( entries ) => {
				entries.forEach( ( entry ) => {
					if ( entry.isIntersecting ) {
						new DSMAnimatedHeadline( entry.target );
						observer.unobserve( entry.target );
					}
				} );
			},
			{
				threshold: 0.1,
			}
		);

		observer.observe( headline );
	} );
} );
