/* jshint esversion: 6 */
( function( $, settings ) {

	'use strict';

	if ( 'function' !== typeof window.wpexLoadMore ) {
		window.wpexLoadMore = function() {

			var $loadMore = $( '.wpex-load-more' );

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

			$loadMore.each( function() {
				const $button = $( this );
				const $wrap = $( this ).parent( '.wpex-load-more-wrap' );
				const $buttonInner = $button.find( '.theme-button-inner' );
				const buttonData = $button.data( 'loadmore' );
				let grid = document.querySelector( buttonData.grid );

				if ( ! grid ) {
					grid = $wrap.get(0).previousElementSibling;
				}

				if ( ! grid ) {
					return;
				}

				const $grid = $( grid );
				const infiniteScroll = buttonData.infinite_scroll || false;
				let page = buttonData.page + 1;
				let loading = false;
				let isotope = null;
				let loadmoreData = buttonData;
				let $newElements = null;

				if ( ! infiniteScroll ) {
					$wrap.css( 'min-height', $wrap.outerHeight() ); // prevent jump when showing loader icon.
				}

				// Renders the grid once it's loaded with ajax.
				var renderGrid = function() {
					// Update counter (before we display items).
					var $counterEl = $grid.find( '[data-count]' );
					if ( $counterEl.length ) {
						loadmoreData.count = parseInt( $counterEl.data( 'count' ) );
						$counterEl.remove();
					}

					// Reload equal heights.
					if ( 'object' === typeof wpex && 'undefined' !== typeof wpex.equalHeights ) {
						wpex.equalHeights();
					}

					// Reload masonry.
					if ( isotope ) {
						isotope.appended( $newElements );
					}

					// Trigger event before displaying items.
					$grid.trigger( 'wpexLoadMoreAddedHidden', [$newElements] );

					// Show items
					$newElements.css( 'opacity', 1 );

					// Triger event after showing items.
					$grid.trigger( 'wpexLoadMoreAddedVisible', [$newElements] );

					// @todo Trigger the core WP "post-load" event
					//$( document.body ).trigger( 'post-load' );

					if ( 'object' === typeof wpex ) {

						// Inline hover styles.
						if ( 'function' === typeof wpex.hoverStyles ) {
							wpex.hoverStyles();
						}

					}

					// Reload sliders.
					if ( 'function' === typeof window.wpexSliderPro ) {
						wpexSliderPro( $newElements );
					}

					// Reload WP embeds.
					if ( 'undefined' !== typeof $.fn.mediaelementplayer ) {
						$newElements.find( 'audio, video' ).mediaelementplayer();
					}

					// Reset button.
					if ( infiniteScroll ) {
						$wrap.addClass( 'wpex-invisible' );
					}
					$wrap.removeClass( 'wpex-loading' );
					$buttonInner.text( settings.i18n.text );

					// Set correct focus.
					if ( ! infiniteScroll ) {
						var $firstLink = $newElements.first().find( 'a' );
						if ( $firstLink.length ) {
							$firstLink.eq(0).focus();
						}
					}

					// Hide button.
					if ( ( page - 1 ) == buttonData.maxPages ) {
						$wrap.hide();
					}

					// Set loading to false.
					loading = false;
				};

				// Click action.
				$button.on( 'click', function() {

					// Check if grid is rendered using isotope.
					// Needs to run on click since wpex.loadMore initiates early.
					if ( 'undefined' !== typeof Isotope ) {
						isotope = Isotope.data( grid );
					}

					if ( ! loading ) {

						loading = true;

						if ( infiniteScroll ) {
							$wrap.removeClass( 'wpex-invisible' );
						}
						$wrap.addClass( 'wpex-loading' );
						$buttonInner.text( settings.i18n.loadingText );

						var data = {
							action   : 'wpex_ajax_load_more',
							nonce    : buttonData.nonce,
							page     : page,
							loadmore : loadmoreData
						};

						$.post( settings.ajax_url, data, function( res ) {

							// Ajax request successful.
							if ( res.success ) {

								//console.log( res.data );

								// Increase page.
								page = page + 1;

								// Define vars
								$newElements = $( res.data );
								$newElements.css( 'opacity', 0 ); // hide until images are loaded.

								// Tweak new items
								$newElements.each( function() {
									var $this = $( this );

									// Add duplicate tag to sticky incase someone want's to hide these.
									if ( $this.hasClass( 'sticky' ) ) {
										$this.addClass( 'wpex-duplicate' );
									}

									// Make sure masonry class exists to prevent issues - @todo deprecate.
									if ( $grid.hasClass( 'wpex-masonry-grid' ) ) {
										$this.addClass( 'wpex-masonry-col' );
									}

								} );

								// Append items.
								$grid.append( $newElements );

								// Render the grid.
								if ( 'function' === typeof imagesLoaded ) {
									imagesLoaded( grid, function() {
										renderGrid();
									} );
								} else {
									renderGrid();
								}

							} // End success.

							else {
								$buttonInner.text( settings.i18n.failedText );
								console.log( res );
							}

						} ).fail( function( xhr, textGridster, e ) {
							console.log( xhr.responseText );
						} );

					} // end loading check.

					return false;

				} ); // End click.

			} ); // End each.

		}; // end wpex.wpexLoadMore.

	} // end wpex.wpexLoadMore check.

	if ( 'function' !== typeof window.wpexLoadMoreInfiniteScroll ) {
		window.wpexLoadMoreInfiniteScroll = function() {
			const isTargets = document.querySelectorAll( '.wpex-load-more--infinite-scroll' );
			let scrollPos = 0;

			if ( ! isTargets ) {
				return;
			}

			const debounce = (callback, wait = 10) => {
				let timeoutId = null;
				return (...args) => {
					window.clearTimeout(timeoutId);
					timeoutId = window.setTimeout(() => {
					  callback.apply(null, args);
					}, wait);
				};
			};

			const isInViewport = ( element ) => {
				const elementTop     = $(element).offset().top;
				const elementBottom  = elementTop + $(element).outerHeight();
				const viewportTop    = $(window).scrollTop();
				const viewportBottom = viewportTop + $(window).height();
				return elementBottom > viewportTop && elementTop < viewportBottom;
			};

			const scrollMonitor = debounce( (ev) => {
				let windowY = window.scrollY;
				if ( windowY > scrollPos ) {
					isTargets.forEach( ( button ) => {
						if ( isInViewport( button ) ) {
							button.click();
						}
					} );
				}
				scrollPos = windowY;
			}, 10);

			window.addEventListener( 'scroll', scrollMonitor );
		};
	}

	$( document ).ready( function() {
		wpexLoadMoreInfiniteScroll();
		wpexLoadMore();
	} );

} ) ( jQuery, wpex_loadmore_params );