( function( $ ) {
	$( window ).on( 'elementor/frontend/init', function() {
		var ModalPopupHandler = elementorModules.frontend.handlers.Base.extend( {

			getDefaultSettings: function() {
				return {
					selectors: {
						wrap: '.pp-modal-popup-wrap',
						overlay: '.pp-modal-popup-overlay',
						window: '.pp-modal-popup-window',
						close: '.pp-modal-popup-close',
						trigger: '.pp-modal-popup-link',
						iframe: '.pp-modal-popup-iframe',
					},
					classes: {
						active: 'pp-modal-popup-active',
						ready: 'pp-modal-popup-ready',
						removing: 'pp-modal-popup-removing',
						preventScroll: 'pp-modal-popup-prevent-scroll',
					},
					transitionTimeout: 600,
				};
			},

			getDefaultElements: function() {
				var selectors = this.getSettings( 'selectors' );
				var $wrap     = this.$element.find( selectors.wrap );
				var widgetId  = this.getID();
				var $overlay  = $( '#pp-modal-popup-overlay-' + widgetId );

				return {
					$wrap: $wrap,
					$overlay: $overlay,
					$window: $overlay.find( selectors.window ),
					$close: $overlay.find( selectors.close ),
					$iframe: $overlay.find( selectors.iframe ),
				};
			},

			onInit: function() {
				elementorModules.frontend.handlers.Base.prototype.onInit.apply( this, arguments );

				this.id            = this.getID();
				this.cookieKey     = 'pp_modal_popup_' + this.id;
				this.isActive      = false;
				this.isOpening     = false;
				this.openTriggered = false;
				this.prevFocus     = null;

				this.config = this.elements.$wrap.data( 'popup-settings' ) || {};

				if ( ! this.elements.$overlay.length ) {
					return;
				}

				this.bindOverlayEvents();

				if ( elementorFrontend.isEditMode() && this.elements.$wrap.hasClass( 'pp-popup-preview' ) ) {
					this.openTriggered = true;
					this.open();
					return;
				}

				if ( this.shouldDisableOnViewport() ) {
					this.elements.$wrap.find( this.getSettings( 'selectors.trigger' ) ).hide();
					return;
				}

				this.initTrigger();
				this.initHashTrigger();
			},

			bindOverlayEvents: function() {
				var self     = this;
				var settings = this.getElementSettings();

				this.elements.$close.on( 'click.pp-popup', function( e ) {
					e.preventDefault();
					e.stopPropagation();
					self.openTriggered = false;
					self.close();
				} );

				if ( 'yes' === settings.click_exit ) {
					this.elements.$overlay.on( 'click.pp-popup', function( e ) {
						if ( ! $( e.target ).closest( self.getSettings( 'selectors.window' ) ).length ) {
							self.openTriggered = false;
							self.close();
						}
					} );
				}

				if ( 'yes' === settings.content_close ) {
					this.elements.$window.on( 'click.pp-popup', function( e ) {
						if ( $( e.target ).closest( self.getSettings( 'selectors.close' ) ).length ) {
							return;
						}
						self.openTriggered = false;
						self.close();
					} );
				}

				if ( 'yes' === settings.esc_exit ) {
					$( document ).on( 'keyup.pp-popup-' + this.id, function( e ) {
						if ( 27 === e.which && self.isActive ) {
							self.openTriggered = false;
							self.close();
						}
					} );
				}

				$( document ).on( 'keydown.pp-popup-' + this.id, function( e ) {
					if ( ! self.isActive || ( 'Tab' !== e.key && 9 !== e.keyCode ) ) {
						return;
					}

					var $focusable = self.elements.$overlay.find(
						'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex]:not([tabindex="-1"]), [contenteditable]'
					).filter( ':visible' );

					if ( ! $focusable.length ) {
						e.preventDefault();
						self.elements.$window.trigger( 'focus' );
						return;
					}

					var first  = $focusable[0];
					var last   = $focusable[ $focusable.length - 1 ];
					var active = document.activeElement;

					if ( e.shiftKey && active === first ) {
						e.preventDefault();
						last.focus();
					} else if ( ! e.shiftKey && active === last ) {
						e.preventDefault();
						first.focus();
					} else if ( ! self.elements.$overlay[0].contains( active ) ) {
						e.preventDefault();
						first.focus();
					}
				} );
			},

			initTrigger: function() {
				var settings = this.getElementSettings();
				var trigger  = settings.trigger;

				switch ( trigger ) {
					case 'page-load':
						this.triggerOnPageLoad();
						break;
					case 'exit-intent':
						this.triggerOnExitIntent();
						break;
					case 'query_parameter':
						this.triggerOnQueryParameter();
						break;
					case 'other':
						this.triggerOnClick( settings.element_identifier || this.getSettings( 'selectors.trigger' ) );
						break;
					case 'on-click':
					default:
						this.triggerOnClick( '.pp-modal-popup-link-' + this.id );
						break;
				}
			},

			triggerOnClick: function( selector ) {
				var self = this;

				if ( ! selector ) {
					return;
				}

				$( document ).on( 'click.pp-popup-' + this.id, selector, function( e ) {
					e.preventDefault();
					self.openTriggered = true;
					self.open( $( this ) );
				} );
			},

			triggerOnPageLoad: function() {
				var self  = this;
				var delay = parseInt( this.config.delay, 10 );

				delay = isNaN( delay ) ? 1000 : delay;

				if ( this.getCookie( this.cookieKey ) ) {
					return;
				}

				setTimeout( function() {
					self.open();
				}, delay );
			},

			triggerOnExitIntent: function() {
				var self = this;

				$( document ).on( 'mouseleave.pp-popup-' + this.id, function( e ) {
					if ( e.clientY > 0 || self.isActive ) {
						return;
					}
					if ( self.getCookie( self.cookieKey ) ) {
						return;
					}
					self.open();
				} );
			},

			triggerOnQueryParameter: function() {
				if ( 1 === parseInt( this.config.queryParameter, 10 ) ) {
					this.open();
				}
			},

			initHashTrigger: function() {
				var self     = this;
				var settings = this.getElementSettings();

				if ( 'yes' !== settings.enable_url_trigger ) {
					return;
				}

				var identifier = ( settings.element_url_identifier || '' ).trim();

				var checkHash = function() {
					var hash = window.location.hash.replace( /^#\/?|\/$/g, '' );

					if ( ! hash ) {
						return;
					}

					if ( identifier && hash === identifier ) {
						self.openTriggered = true;
						self.open();
						return;
					}

					if ( hash === 'modal-' + self.id ) {
						self.openTriggered = true;
						self.open();
					}
				};

				$( window ).on( 'load.pp-popup-' + this.id + ' hashchange.pp-popup-' + this.id, checkHash );

				$( document ).on( 'click.pp-popup-' + this.id, 'a[href*="#"]', function( e ) {
					var href      = $( this ).attr( 'href' ) || '';
					var hashIndex = href.indexOf( '#' );

					if ( hashIndex < 0 ) {
						return;
					}

					var hash = href.substring( hashIndex + 1 );

					if ( ! hash ) {
						return;
					}

					if ( ( identifier && hash === identifier ) || hash === 'modal-' + self.id ) {
						e.preventDefault();
						self.openTriggered = true;
						self.open();
					}
				} );
			},

			shouldDisableOnViewport: function() {
				var disableOn = parseInt( this.config.disableOn, 10 );

				if ( ! disableOn ) {
					return false;
				}

				return $( window ).width() < disableOn;
			},

			open: function( $clicker ) {
				var self     = this;
				var settings = this.getElementSettings();

				if ( this.isActive || this.isOpening ) {
					return;
				}

				this.isOpening = true;

				if ( $clicker && $clicker.length ) {
					this.prevFocus = $clicker;
				} else {
					this.prevFocus = $( document.activeElement );
				}

				this.setIframeSrc();
				this.setExitAnimationClass( true );

				this.elements.$overlay.addClass( this.getSettings( 'classes.active' ) ).attr( 'aria-hidden', 'false' );

				if ( 'yes' === settings.prevent_scroll ) {
					$( 'html' ).addClass( this.getSettings( 'classes.preventScroll' ) );
				}

				// Force reflow so adding the ready class triggers a CSS transition.
				void this.elements.$overlay[0].offsetHeight;

				requestAnimationFrame( function() {
					self.elements.$overlay.addClass( self.getSettings( 'classes.ready' ) );
				} );

				this.isActive  = true;
				this.isOpening = false;

				setTimeout( function() {
					self.elements.$window.trigger( 'focus' );
				}, 100 );

				this.setReTriggerCookie();

				$( document ).trigger( 'ppe-popup-opened', [ this.id, this ] );
				this.elements.$overlay.trigger( 'pp:popup:open' );
			},

			close: function() {
				var self     = this;
				var settings = this.getElementSettings();

				if ( ! this.isActive ) {
					return;
				}

				var classes      = this.getSettings( 'classes' );
				var transitionMs = this.getSettings( 'transitionTimeout' );
				var hasExitAnim  = this.setExitAnimationClass();

				this.elements.$overlay.removeClass( classes.ready ).addClass( classes.removing );

				var finalize = function() {
					self.elements.$overlay.removeClass( classes.active + ' ' + classes.removing );
					self.setExitAnimationClass( true );
					self.clearIframeSrc();
					self.pauseMedia();
					self.elements.$overlay.attr( 'aria-hidden', 'true' );

					if ( 'yes' === settings.prevent_scroll ) {
						$( 'html' ).removeClass( classes.preventScroll );
					}

					self.isActive = false;

					if ( self.prevFocus && self.prevFocus.length && ! elementorFrontend.isEditMode() ) {
						self.prevFocus.trigger( 'focus' );
					}

					$( document ).trigger( 'ppe-popup-closed', [ self.id, self ] );
					self.elements.$overlay.trigger( 'pp:popup:close' );
				};

				if ( 'none' === settings.popup_animation_out ) {
					finalize();
				} else if ( hasExitAnim || settings.popup_animation_in ) {
					setTimeout( finalize, transitionMs );
				} else {
					finalize();
				}
			},

			setExitAnimationClass: function( remove ) {
				var settings = this.getElementSettings();
				var anim     = settings.popup_animation_out;

				if ( ! anim ) {
					return false;
				}

				var cls = 'pp-anim-out-' + anim.replace( /^mfp-/, '' );

				if ( remove ) {
					this.elements.$overlay.removeClass( cls );
				} else {
					this.elements.$overlay.addClass( cls );
				}

				return true;
			},

			setIframeSrc: function() {
				var $iframe = this.elements.$iframe;

				if ( ! $iframe.length ) {
					return;
				}

				var src = $iframe.attr( 'data-src' );

				if ( ! src ) {
					return;
				}

				if ( ( src.indexOf( 'youtube' ) !== -1 || src.indexOf( 'vimeo' ) !== -1 ) && src.indexOf( 'autoplay=1' ) === -1 ) {
					src += ( src.indexOf( '?' ) !== -1 ? '&' : '?' ) + 'autoplay=1&rel=0';
				}

				$iframe.attr( 'src', src );
			},

			clearIframeSrc: function() {
				var $iframe = this.elements.$iframe;

				if ( ! $iframe.length ) {
					return;
				}

				$iframe.attr( 'src', '' );
			},

			pauseMedia: function() {
				var $window = this.elements.$window;

				$window.find( 'video, mux-player' ).each( function() {
					if ( typeof this.pause === 'function' ) {
						this.pause();
					}
				} );
			},

			setReTriggerCookie: function() {
				var displayAfter = parseInt( this.config.displayAfter, 10 );

				if ( isNaN( displayAfter ) || displayAfter <= 0 ) {
					this.removeCookie( this.cookieKey );
					return;
				}

				this.setCookie( this.cookieKey, '1', displayAfter );
			},

			setCookie: function( name, value, days ) {
				var maxAge = 60 * 60 * 24 * parseInt( days, 10 );
				document.cookie = name + '=' + encodeURIComponent( value ) + '; path=/; max-age=' + maxAge;
			},

			getCookie: function( name ) {
				var parts = ( '; ' + document.cookie ).split( '; ' + name + '=' );

				if ( 2 === parts.length ) {
					return decodeURIComponent( parts.pop().split( ';' ).shift() );
				}

				return false;
			},

			removeCookie: function( name ) {
				document.cookie = name + '=; path=/; max-age=0';
			},

			onElementChange: function( setting ) {
				if ( ! elementorFrontend.isEditMode() ) {
					return;
				}

				if ( 'preview_popup' === setting ) {
					if ( 'yes' === this.getElementSettings( 'preview_popup' ) ) {
						this.openTriggered = true;
						this.open();
					} else {
						this.close();
					}
				}
			},

			onDestroy: function() {
				$( document ).off( '.pp-popup-' + this.id );
				$( window ).off( '.pp-popup-' + this.id );

				if ( this.elements.$overlay && this.elements.$overlay.length ) {
					this.elements.$overlay.off( '.pp-popup' );
				}

				$( 'html' ).removeClass( this.getSettings( 'classes.preventScroll' ) );

				elementorModules.frontend.handlers.Base.prototype.onDestroy.apply( this, arguments );
			},
		} );

		elementorFrontend.elementsHandler.attachHandler( 'pp-modal-popup', ModalPopupHandler );
	} );
}( jQuery ) );
