// Imagify tabs ====================================================================================
(function ($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names

	/**
	 * @Markup:
	 * ul.imagify-tabs
	 *     li.imagify-tab.imagify-current
	 *         a[href="#target"]
	 * div.imagify-tabs-contents
	 *     div.imagify-tab-content#target
	 */
	$(d).on('click.imagify', '.imagify-tab', function (e) {
		var $_this = $(this),
			curr_class = 'imagify-current',
			target;

		e.preventDefault();

		if ($_this.hasClass('imagify-current')) {
			return;
		}

		target = $_this.find('a').attr('href') || '#' + $_this.find('a').attr('aria-controls');

		// Show right tab content.
		$_this.closest('.imagify-tabs').next('.imagify-tabs-contents').find('.imagify-tab-content').hide().attr('aria-hidden', 'true');
		$(target).fadeIn(275).attr('aria-hidden', 'false');

		// Change active tabs.
		$_this.closest('.imagify-tabs').find('.imagify-tab').removeClass(curr_class).attr('aria-selected', 'false');
		$_this.addClass(curr_class).attr('aria-selected', 'true');
	});

})(jQuery, document, window);


// Imagify payment modal ===========================================================================
(function ($, d, w, undefined) { // eslint-disable-line no-unused-vars, no-shadow, no-shadow-restricted-names

	/**
	 * Payment Modal.
	 *
	 * @since  1.6
	 * @since  1.6.3 include discount campaign
	 * @author Geoffrey
	 */
	var imagifyModal = {};

	if (! $('#imagify-pricing-modal').length) {
		return;
	}

	imagifyModal = {
		$modal:       $('#imagify-pricing-modal'),
		$checkboxes:  $('.imagify-offer-line .imagify-checkbox'),
		$radios:      $('.imagify-payment-modal .imagify-radio-line input'),
		// Plans selection view & payment process view hidden by default.
		$preView:     $('#imagify-pre-checkout-view'),
		$plansView:   $('#imagify-plans-selection-view').hide(),
		$paymentView: $('#imagify-payment-process-view').hide(),
		$successView: $('#imagify-success-view').hide(),
		$anotherBtn:  $('.imagify-choose-another-plan'),
		speedFadeIn:  300,

		getHtmlPrice: function (content, period) {
			var monthly, yearly, m, y, output;

			if (! period) {
				period = null;
			}

			if (typeof content !== 'object') {
				content += ''; // Be sure content is a string.
				content = content.split('.');
				content[1] = content[1].length === 1 ? content[1] + '0' : ('' + content[1]).substring(0, 2);

				output = '<span class="imagify-price-big">' + content[0] + '</span> ';
				output += '<span class="imagify-price-mini">.' + content[1] + '</span>';

				return output;
			}

			monthly = content.monthly + '';
			yearly = content.yearly + '';
			m = '0' === monthly ? ['0', '00'] : monthly.split('.');
			y = '0' === yearly ? ['0', '00'] : yearly.split('.');
			output = '<span class="imagify-switch-my">';
			/* eslint-disable indent */
			output += '<span aria-hidden="' + (period === 'monthly' ? 'false' : 'true') + '" class="imagify-monthly">';
			output += '<span class="imagify-price-big">' + m[0] + '</span> ';
			output += '<span class="imagify-price-mini">.' + (m[1].length === 1 ? m[1] + '0' : ('' + m[1]).substring(0, 2)) + '</span>';
			output += '</span> ';
			output += '<span aria-hidden="' + (period === 'yearly' ? 'false' : 'true') + '" class="imagify-yearly">';
			output += '<span class="imagify-price-big">' + y[0] + '</span> ';
			output += '<span class="imagify-price-mini">.' + (y[1].length === 1 ? y[1] + '0' : ('' + y[1]).substring(0, 2)) + '</span>';
			output += '</span>';
			/* eslint-enable indent */
			output += '</span>';

			return output;
		},

		getHtmlDiscountPrice: function (content, period) {
			var monthly, yearly,
				output = '';

			if (! period) {
				period = null;
			}

			if (typeof content === 'object') {
				monthly = content.monthly + '';
				yearly = content.yearly + '';

				output += '<span class="imagify-price-discount">';
				/* eslint-disable indent */
				output += '<span class="imagify-price-discount-dollar">$</span>';
				output += '<span class="imagify-switch-my">';
				output += '<span aria-hidden="' + (period === 'monthly' ? 'false' : 'true') + '" class="imagify-monthly">';
				output += '<span class="imagify-price-discount-number">' + monthly + '</span>';
				output += '</span>';
				output += '<span aria-hidden="' + (period === 'yearly' ? 'false' : 'true') + '" class="imagify-yearly">';
				output += '<span class="imagify-price-discount-number">' + yearly + '</span>';
				output += '</span>';
				output += '</span>';
				/* eslint-enable indent */
				output += '</span>';
			} else {
				content += ''; // Be sure content is a string.
				output += '<span class="imagify-price-discount">';
				/* eslint-disable indent */
				output += '<span class="imagify-price-discount-dollar">$</span>';
				output += '<span class="imagify-price-discount-number">' + content + '</span>';
				/* eslint-enable indent */
				output += '</span>';
			}

			return output;
		},

		/**
		 * @uses imagifyModal.getHtmlPrice()
		 * @uses imagifyModal.getHtmlDiscountPrice()
		 */
		populateOffer: function ($offer, datas, type, classes) {
			var promo = w.imagify_discount_datas,
				add = datas.additional_gb,   // 4 (monthly)
				ann = datas.annual_cost,     // 49.9 (monthly)
				id = datas.id,              // 3 (monthly/onetime)
				lab = datas.label,           // 'lite' (monthly/onetime)
				mon = datas.monthly_cost,    // 4.99 (monthly)
				quo = datas.quota,           // 1000 (MB) - 5000 images (monthly/onetime)
				cos = datas.cost,            // 3.49 (onetime)
				name = -1 === quo ? 'Unlimited' : (quo >= 1000 ? quo / 1000 + ' GB' : quo + ' MB'),
				pcs = 'monthly' === type ? {monthly: mon, yearly: Math.round(ann / 12 * 100) / 100} : cos,
				pcsd = pcs, // Used if discount is active.
				percent, $datas_c, datas_content, applies_to = [];

			applies_to = imagifyModal.getPromoAppliesTo(promo);


			// Change pricing value only if discount in percentage is active and if offer is a monthly and not a onetime.
			if (
				promo.is_active
				&& 'percentage' === promo.coupon_type
				&& 'monthly' === type
				&& (0 < mon)
				&& (applies_to.includes(lab) || 'all' === applies_to[0])
			) {
				percent = (100 - promo.coupon_value) / 100;
				pcs = 'monthly' === type ? {
					monthly: mon * percent,
					yearly:  Math.round((ann * percent) / 12 * 100) / 100
				} : cos * percent;
			}

			if (typeof classes !== 'undefined') {
				$offer.addClass('imagify-' + type + '-' + lab + classes);
			}

			// Name.
			$offer.find('.imagify-offer-size').text(name);

			// Main prices (pcs can be an object or a string).
			$offer.find('.imagify-number-block').html(imagifyModal.getHtmlPrice(pcs, 'monthly'));

			// discount prices
			$offer.find('.imagify-price-block').prev('.imagify-price-discount').remove();
			if (
				promo.is_active
				&& 'percentage' === promo.coupon_type
				&& 'monthly' === type
				&& (0 < mon)
				&& (applies_to.includes(lab) || 'all' === applies_to[0])
			) {
				$offer.find('.imagify-price-block').before(imagifyModal.getHtmlDiscountPrice(pcsd, 'monthly'));
			}
			// Nb images.
			$offer.find('.imagify-approx-nb').text(quo * 5);

			if ('monthly' === type) {
				// Additional price.
				$offer.find('.imagify-price-add-data').text('$' + add);
			}

			// Button data-offer attr.
			$datas_c = $offer.find('.imagify-payment-btn-select-plan').length ? $offer.find('.imagify-payment-btn-select-plan') : $offer;

			if ('monthly' === type) {
				datas_content = '{"' + lab + '":{"id":' + id + ',"name":"' + name + '","label":"' + lab + '","data":' + quo + ',"dataf":"' + name + '","imgs":' + (quo * 5) + ',"prices":{"monthly":' + pcs.monthly + ',"yearly":' + pcs.yearly + ',"add":' + add + '}}}';
			} else {
				datas_content = '{"ot' + lab + '":{"id":' + id + ',"name":"' + name + '","label":"' + lab + '","data":' + quo + ',"dataf":"' + name + '","imgs":' + (quo * 5) + ',"price":' + pcs + '}}';
			}

			$datas_c.attr('data-offer', datas_content);

			return $offer;
		},

		populatePayBtn: function () {
			var $monthlyOffer = $('.imagify-offer-monthly'),
				$onetimeOffer = $('.imagify-offer-onetime'),
				pl_datas, ot_datas,
				price = 0,
				price_pl = 0,
				price_ot = 0;

			if ($monthlyOffer.length) {
				pl_datas = JSON.parse($monthlyOffer.attr('data-offer'));
				// Calculate price_pl only if that offer is selected.
				if ($monthlyOffer.hasClass('imagify-offer-selected')) {
					if ($('#imagify-subscription-monthly').filter(':checked').length) {
						price_pl = pl_datas[Object.keys(pl_datas)[0]].prices.monthly;
					} else {
						price_pl = pl_datas[Object.keys(pl_datas)[0]].prices.yearly * 12;
					}
				}
			}

			if ($onetimeOffer.length) {
				ot_datas = JSON.parse($onetimeOffer.attr('data-offer'));
				// Calculate price_ot only if that offer is selected.
				if ($onetimeOffer.hasClass('imagify-offer-selected')) {
					price_ot = ot_datas[Object.keys(ot_datas)[0]].price;
				}
			}

			// Calculate price.
			price = parseFloat(price_ot + price_pl).toFixed(2);

			// Edit button price.
			//$( '.imagify-global-amount' ).text( price ); // Not used.

			if ('0.00' === price || 0 === price) {
				$('#imagify-modal-checkout-btn').prop('disabled', true).addClass('imagify-button-disabled');
			} else {
				$('#imagify-modal-checkout-btn').prop('disabled', false).removeClass('imagify-button-disabled');
			}
		},

		checkCoupon: function () {
			var code = $('#imagify-coupon-code').val(),
				$cptext, $label, $section, nonce;

			$cptext = $('.imagify-coupon-text');
			$label = $cptext.find('label');
			$section = $('.imagify-coupon-section');

			if ('' === code) {
				$section.removeClass('validated').removeClass('invalid');
				$label.html(imagifyPricingModal.labels.defaultCouponLabel);
				return;
			}

			nonce = $('#imagify-get-pricing-modal').data('nonce');

			$cptext.addClass('checking');

			// Get the true prices.
			$.post(ajaxurl, {action: 'imagify_check_coupon', coupon: code, imagifynonce: nonce}, function (response) {
				var coupon_value;

				$cptext.removeClass('checking');

				// Error during the request.
				if (! response.success) {
					$section.removeClass('validated').addClass('invalid');
					$label.text(imagifyPricingModal.labels.errorCouponAPI);
				} else if (response.data.success) {
					coupon_value = 'percentage' === response.data.coupon_type ? response.data.value + '%' : '$' + response.data.value;
					var $selected_plan_line = $('.imagify-pre-checkout-view .imagify-pre-checkout-offers .imagify-offer-line');
					var	offer_data = JSON.parse($selected_plan_line.attr('data-offer'));
					var applies_to = imagifyModal.getPromoAppliesTo(response.data);
					if ( applies_to.includes(offer_data[Object.keys(offer_data)[0]].label ) || "all" === applies_to[0] ){
						$section.removeClass('invalid').addClass('validated');
						$label.html(imagifyPricingModal.labels.successCouponAPI);
						$label.find('.imagify-coupon-offer').text(coupon_value);
						$label.find('.imagify-coupon-word').text(code);
					} else {
						$section.removeClass('validated').addClass('invalid');
						$label.html(imagifyPricingModal.labels.errorCouponPlan);
						$('#imagify-coupon-code').val('');

					}
				} else {
					$section.removeClass('validated').addClass('invalid');
					$label.text(response.data.detail);
				}
			});
		},

		/**
		 * @uses imagifyModal.populateOffer()
		 * @uses imagifyModal.populatePayBtn()
		 * @uses imagifyModal.checkCoupon()
		 */
		getPricing: function ($button) {
			var nonce = $button.data('nonce'),
				prices_rq_datas = {
					action:       'imagify_get_prices',
					imagifynonce: nonce
				},
				imgs_rq_datas = {
					action:       'imagify_get_images_counts',
					imagifynonce: nonce
				},
				prices_rq_discount = {
					action:       'imagify_get_discount',
					imagifynonce: nonce
				};

			imagifyModal.$modal.find('.imagify-modal-loader').hide().show();
			imagifyModal.$modal.addClass('imagify-modal-loading');

			/**
			 * TODO: change the way to waterfall requests.
			 * Use setInterval + counter instead.
			 */

			// Get the true prices.
			$.post(ajaxurl, prices_rq_datas, function (prices_response) {

				if (! prices_response.success) {
					// TODO: replace modal content by any information.
					// An error occurred.

					// Populate Pay button.
					imagifyModal.populatePayBtn();
					return;
				}

				// get the image estimates sizes
				$.post(ajaxurl, imgs_rq_datas, function (imgs_response) {

					if (! imgs_response.success) {
						// TODO: replace modal content by any information.
						// An error occurred.
						return;
					}

					// Get the discount informations.
					$.post(ajaxurl, prices_rq_discount, function (discount_response) {
						var images_datas, prices_datas, promo_datas,
							offers, consumption, suggested,
							freeQuota = 25,
							ot_html = '',
							mo_html = '',
							$mo_tpl, $ot_tpl,
							ot_clone, mo_clone,
							$estim_block, $offers_block,
							$banners, date_end, plan_names, promo, discount;

						if (! discount_response.success) {
							// TODO: replace modal content by any information.
							// An error occurred.
							return;
						}

						images_datas = imgs_response.data;
						prices_datas = prices_response.data;
						promo_datas = discount_response.data;
						offers = {
							mo: [],
							ot: []
						};
						consumption = {
							month: images_datas.average_month_size.raw / Math.pow(1024, 2), // Bytes to MB.
							total: images_datas.total_library_size.raw / Math.pow(1024, 2)  // Bytes to MB.
						};
						$mo_tpl = $('#imagify-offer-monthly-template');
						$ot_tpl = $('#imagify-offer-onetime-template');
						ot_clone = $ot_tpl.html();
						mo_clone = $mo_tpl.html();
						$estim_block = $('.imagify-estimation-block');

						// Remove inactive offers.
						$.each(prices_datas.monthlies, function (index, value) {
							if ('undefined' === typeof value.active
								||
								('undefined' !== typeof value.active && true === value.active)
							) {
								if ('free' === value.label) {
									freeQuota = value.quota;
								}
								offers.mo.push(value);
							}
						});
						$.each(prices_datas.onetimes, function (index, value) {
							if ('undefined' === typeof value.active
								||
								('undefined' !== typeof value.active && true === value.active)
							) {
								offers.ot.push(value);
							}
						});

						// Refresh Analyzing block.
						$estim_block.removeClass('imagify-analyzing');
						$estim_block.find('.average-month-size').text(images_datas.average_month_size.human);
						$estim_block.find('.total-library-size').text(images_datas.total_library_size.human);

						// Switch offers title if < 25mb.
						if (consumption.total + consumption.month < freeQuota) {
							$('.imagify-pre-checkout-offers .imagify-modal-title').addClass('imagify-enough-free');
						} else {
							$('.imagify-enough-free').removeClass('imagify-enough-free');
						}

						// Reset offer selection.
						$('.imagify-offer-selected').removeClass('imagify-offer-selected').find('.imagify-checkbox').prop('checked', false);

						// Don't create prices table if something went wrong during request.
						if (null === offers.mo || null === offers.ot) {
							$offers_block = $('.imagify-pre-checkout-offers');

							// Hide main content.
							$offers_block.hide().attr('aria-hidden', true);

							// Show error message.
							$offers_block.closest('.imagify-modal-views').find('.imagify-popin-message').remove();
							$offers_block.after('<div class="imagify-popin-message imagify-error"><p>' + imagifyPricingModal.labels.errorPriceAPI + '</p></div>');

							// Show the modal content.
							imagifyModal.$modal.find('.imagify-modal-loader').fadeOut(300);
							imagifyModal.$modal.removeClass('imagify-modal-loading');
							return;
						}

						// Autofill coupon code & Show banner if discount is active.
						w.imagify_discount_datas = promo_datas;

						if (promo_datas.is_active) {
							if (promo_datas.applies_to instanceof Array) {
								plan_names = [];
								var plan_list = [];

								for (var plan_infos = 0; plan_infos < promo_datas.applies_to.length; plan_infos++) {
									plan_list.push(promo_datas.applies_to[plan_infos].plan_name);
								}

								plan_list.forEach(function (item) {
									if (! plan_names.includes(item)) {
										plan_names.push(item);
									}
								});

								plan_names = plan_names.join(', ');
							} else {
								plan_names = promo_datas.applies_to;
							}

							$banners = $('.imagify-modal-promotion');
							date_end = promo_datas.date_end.split('T')[0];
							promo = promo_datas.coupon_value;
							discount = 'percentage' === promo_datas.coupon_type ? promo + '%' : '$' + promo;


							// Show banners.
							$banners.addClass('active').attr('aria-hidden', 'false');

							// Populate banners.
							$banners.find('.imagify-promotion-number').text(discount);
							$banners.find('.imagify-promotion-plan-name').text(plan_names);
							$banners.find('.imagify-promotion-date').text(date_end);

						}

						/**
						 * Find which plan(s) should be pre-selected.
						 */
						suggested = imagifyModal.getSuggestedOffers(offers, consumption, freeQuota);

						/**
						 * Below lines will build Plan and Onetime offers lists.
						 * It will also pre-select a Plan and/or Onetime in both of views: pre-checkout and pricing tables.
						 */
						if (0 === offers.mo.length) {
							$('.imagify-pre-checkout-offers .imagify-offer-monthly').remove();
							$('.imagify-tabs').remove();
							$('.imagify-pricing-tab-monthly').remove();
						} else {
							// Now, do the MONTHLIES Markup.
							$.each(offers.mo, function (index, value) {
								var $tpl, $offer,
									classes = '';

								// If offer is too big (far) than estimated needs, don't show the offer.
								if ((index - suggested.mo.index) > 2) {
									return true;
								}

								if (index === suggested.mo.index) {
									// It's the one to display.
									$offer = $('.imagify-pre-checkout-offers .imagify-offer-monthly');

									if (suggested.mo.selected) {
										classes = ' imagify-offer-selected';

										// Add this offer as pre-selected item in pre-checkout view.
										$offer.addClass('imagify-offer-selected').find('.imagify-checkbox').prop('checked', true);
									}
									// Populate the Pre-checkout view depending on user_cons.
									imagifyModal.populateOffer($offer, value, 'monthly');
								}

								// Populate each offer.
								$tpl = $(mo_clone).clone();
								$tpl = imagifyModal.populateOffer($tpl, value, 'monthly', classes);

								// Complete Monthlies HTML.
								mo_html += $tpl[0].outerHTML;
							});
						}

						if (0 === offers.ot.length) {
							$('.imagify-pre-checkout-offers .imagify-offer-onetime').remove();
							$('.imagify-tabs').remove();
							$('.imagify-pricing-tab-onetime').remove();
						} else {
							// Do the ONETIMES Markup.
							$.each(offers.ot, function (index, value) {
								var $tpl, $offer,
									classes = '';

								// Parent classes.
								if (index === suggested.ot.index) {
									$offer = $('.imagify-pre-checkout-offers .imagify-offer-onetime');

									if (suggested.ot.selected) {
										classes = ' imagify-offer-selected';

										// Add this offer as pre-selected item in pre-checkout view.
										$offer.addClass('imagify-offer-selected').find('.imagify-checkbox').prop('checked', true);
									}

									// Populate the Pre-checkout view depending on user_cons.
									imagifyModal.populateOffer($offer, value, 'onetime');
								}

								// Populate each offer.
								$tpl = $(ot_clone).clone();
								$tpl = imagifyModal.populateOffer($tpl, value, 'onetime', classes);

								// complete Onetimes HTML
								ot_html += $tpl[0].outerHTML;
							});
						}
						if (promo_datas){
							var applies_to = imagifyModal.getPromoAppliesTo(promo_datas);
							if ( applies_to.includes(suggested.mo.plan_label) || applies_to.includes(suggested.ot.plan_label) || 'all' === applies_to[0]){
								$('#imagify-coupon-code').val(promo_datas.label);
							}
							if (promo_datas.is_active) {
								imagifyModal.checkCoupon();
							}
						}
						// Fill pricing tables.
						if ($mo_tpl.parent().find('.imagify-offer-line')) {
							$mo_tpl.parent().find('.imagify-offer-line').remove();
						}

						$mo_tpl.before(mo_html);

						if ($ot_tpl.parent().find('.imagify-offer-line')) {
							$ot_tpl.parent().find('.imagify-offer-line').remove();
						}

						$ot_tpl.before(ot_html);

						// Show the content.
						imagifyModal.$modal.find('.imagify-modal-loader').fadeOut(300);
						imagifyModal.$modal.removeClass('imagify-modal-loading');

					}); // Third AJAX request to get discount information.

				}); // Second AJAX request for image estimation sizes.

				// Populate Pay button.
				imagifyModal.populatePayBtn();
			}); // End $.post.
		},

		/**
		 * Tell which offer(s) should be pre-selected.
		 *
		 * @param object offers {
		 *     An object build like this:
		 *
		 *     @type array mo Monthly offers. The most important data being 'quota' (MBytes).
		 *     @type array ot One-Time offers. The most important data being 'quota' (MBytes).
		 * }
		 * @param object consumption {
		 *     An object build like this:
		 *
		 *     @type array month Average image size uploaded each month on the site (MBytes).
		 *     @type array total Total image size in the library (MBytes).
		 * }
		 * @param int    freeQuota Quota of the free monthly offer (MBytes). Currently 25.
		 * @return object {
		 *     An object build like this:
		 *
		 *     @type object mo An object containing the index of the suggested monthly offer, and if it should be selected.
		 *     @type object ot An object containing the index of the suggested one-time offer, and if it should be selected.
		 * }
		 */
		getSuggestedOffers: function (offers, consumption, freeQuota) {
			var tmpMB = consumption.total + consumption.month,
				plan,
				biggestPlan = {
					quota: 0
				},
				unlimitedPlan,
				suggested = {
					mo: false,
					ot: false
				};

			if (0 > offers.ot.length){
				var last_ot_plan_id = offers.ot[offers.ot.length - 1].id;
				var last_ot_plan_label = offers.ot[offers.ot.length - 1].label;
			}
			if (0 > offers.ot.length){
				var last_mo_plan_id = offers.mo[offers.mo.length - 1].id;
				var last_mo_plan_label = offers.mo[offers.mo.length - 1].label;
			}
			/**
			 * Paid monthly plan.
			 */
			$.each(offers.mo, function (index, value) {
				// if this is the unlimited plan, save it; we may need to come back to it.
				if (0 > value.quota) {
					unlimitedPlan = {
						index:      index,
						selected:   1,
						plan_id:    value.id,
						plan_label: value.label
					};
				}

				// This is the biggest plan we've seen so far. Save it in case we need it later.
				if (value.quota > biggestPlan.quota) {
					biggestPlan = {
						index:      index,
						selected:   1,
						quota:      value.quota,
						plan_id:    value.id,
						plan_label: value.label
					};
				}

				// Skip the free plan.
				if ((0 === value.monthly_cost) && (0 === value.annual_cost)) {
					return true;
				}

				// For all except unlimited plan: Rule out this plan if quota is less than either library size or monthly usage.
				if ((0 >= value.quota) && (consumption.month > value.quota) || (consumption.total > value.quota)) {
					return true;
				}

				// For all except unlimited plan: Consider this plan if its quota meets consumption needs.
				if ((0 <= value.quota) && (consumption.month < value.quota) && (consumption.total < value.quota)) {
					// Select this one when (1) we haven't yet selected a plan, or (2) when this plan is less quota than the current one.
					if (('undefined' === typeof plan) || (plan.quota > value.quota)) {
						plan = value;
						suggested.mo = {
							index:      index,
							selected:   (freeQuota > consumption.month) && (freeQuota > consumption.total) ? 0 : 1,
							plan_id:    value.id,
							plan_label: value.label
						};
					}

					return true;
				}

				return true;
			});

			// If we don't have a plan selected by the time we get here, we need the infinite plan, or the biggest if infinite isn't available.
			if (false === suggested.mo) {
				if ('undefined' !== typeof unlimitedPlan) {
					suggested.mo = unlimitedPlan;
				} else {
					suggested.mo = biggestPlan;
				}
			}
			// Remaining MB.
			tmpMB -= offers.mo[suggested.mo.index].quota;

			// If we don't have active onetime plans, we're done.
			if (0 === offers.ot.length) {
				return suggested;
			}

			if (tmpMB <= 0) {
				/**
				 * The monthly plan is big enough to optimize all the images that already are in the library.
				 * We'll display a One-Time plan that is able to optimize the whole library, in case the user doesn't want a monthly plan, but it won't be pre-selected.
				 */
				$.each(offers.ot, function (index, value) {
					if (value.quota < consumption.total) {
						// This plan is not big enough for the user needs.
						return true;
					}

					// Suggested monthly plan.
					suggested.ot = {
						index:      index,
						selected:   0,
						plan_id:    value.id,
						plan_label: value.label
					};
					return false;
				});

				if (false === suggested.ot) {
					suggested.ot = {
						index:      offers.ot.length - 1,
						selected:   0,
						plan_id:    last_ot_plan_id,
						plan_label: last_ot_plan_label
					};
				}

				return suggested;
			}

			/**
			 * The monthly plan is not big enough to optimize all the images that already are in the library.
			 * We need to select a One-Time plan.
			 */
			$.each(offers.ot, function (index, value) {
				if (value.quota < tmpMB) {
					// This plan is not big enough for the user needs.
					return true;
				}

				// Suggested one-time plan.
				suggested.ot = {
					index:      index,
					selected:   1,
					plan_id:    value.id,
					plan_label: value.label
				};
				return false;
			});

			if (false !== suggested.ot) {
				// OK, we have all we need.
				return suggested;
			}

			/**
			 * If nothing is selected, that means no OT plan is big enough for the user.
			 * In that case we fallback to the biggest available, and we need to increase the monthly plan.
			 */
			suggested.ot = {
				index:      offers.ot.length - 1,
				selected:   1,
				plan_id:    last_ot_plan_id,
				plan_label: last_ot_plan_label
			};

			// Reset monthly plan.
			suggested.mo = false;

			// Reset the remaining MB and subtract the OT plan quota.
			tmpMB = consumption.total + consumption.month - offers.ot[suggested.ot.index].quota;

			// Search for a new monthly plan.
			$.each(offers.mo, function (index, value) {
				if (value.quota < tmpMB) {
					// This plan is not big enough for the user needs.
					return true;
				}

				// Suggested monthly plan.
				suggested.mo = {
					index:      index,
					selected:   1,
					plan_id:    value.id,
					plan_label: value.label
				};
				return false;
			});

			if (false === suggested.mo) {
				/**
				 * If nothing is selected, that means no monthly plan is big enough for the user's monthly consumption.
				 * In that case we fallback to the biggest available.
				 */
				suggested.mo = {
					index:      offers.mo.length - 1,
					selected:   1,
					plan_id:    last_mo_plan_id,
					plan_label: last_mo_plan_label
				};
			}

			return suggested;
		},

		/**
		 * @uses imagifyModal.populatePayBtn()
		 */
		checkCheckbox: function ($checkbox) {
			var sel_class = 'imagify-offer-selected';

			$checkbox.each(function () {
				var $this = $(this);

				if ($this.is(':checked')) {
					$this.closest('.imagify-offer-line').addClass(sel_class);
				} else {
					$this.closest('.imagify-offer-line').removeClass(sel_class);
				}
			});

			// Update pay button.
			imagifyModal.populatePayBtn();
		},

		/**
		 * @uses imagifyModal.populatePayBtn()
		 */
		checkRadio: function ($radio) {
			var year_class = 'imagify-year-selected',
				month_class = 'imagify-month-selected';

			$radio.each(function () {
				// To handle modal pricing & modal suggestion.
				var $_this = $(this),
					$parent, $to_switch;

				if ($_this.parent('.imagify-cart-list-switcher').length) {
					$parent = $_this.closest('.imagify-cart');
				} else if ($_this.parent('.imagify-small-options').length) {
					$parent = $_this.parent('.imagify-small-options').next('.imagify-pricing-table');
				} else {
					$parent = $_this.closest('.imagify-offer-line');
				}

				$to_switch = $parent.find('.imagify-switch-my');

				if ($_this.val() === 'yearly') {
					$parent.addClass(year_class).removeClass(month_class);
					$to_switch.find('.imagify-monthly').attr('aria-hidden', 'true');
					$to_switch.find('.imagify-yearly').attr('aria-hidden', 'false');
				} else {
					$parent.addClass(month_class).removeClass(year_class);
					$to_switch.find('.imagify-monthly').attr('aria-hidden', 'false');
					$to_switch.find('.imagify-yearly').attr('aria-hidden', 'true');
				}
			});

			// Update Pay button information.
			imagifyModal.populatePayBtn();

			return $radio;
		},

		/**
		 * Currently not used.
		 * @uses imagifyModal.populatePayBtn()
		 */
		populateBtnPrice: setInterval(function () {
			imagifyModal.populatePayBtn();
		}, 1000),

		/**
		 * 1) Modal Payment change/select plan
		 * 2) Checkout selection(s)
		 * 3) Payment process
		 */

		getPeriod: function () {
			return $('.imagify-offer-monthly').hasClass('imagify-month-selected') ? 'monthly' : 'yearly';
		},

		getApiKey: function () {
			return $('#imagify-payment-iframe').data('imagify-api');
		},

		switchToView: function ($view, data) {

			var viewId = $view.attr('id'),
				$modalContent = imagifyModal.$modal.children('.imagify-modal-content');

			$view.siblings('.imagify-modal-views').hide().attr('aria-hidden', 'true');

			// Plans view has tabs: display the right one.
			if (data && data.tab) {
				$view.find('a[href="#' + data.tab + '"]').trigger('click.imagify');
			}

			// Payment view: it's an iframe.
			if ('imagify-payment-process-view' === viewId) {
				$modalContent.addClass('imagify-iframe-viewing');
			} else {
				$modalContent.removeClass('imagify-iframe-viewing');
			}

			// Success view: some tweaks.
			if ('imagify-success-view' === viewId) {
				$modalContent.addClass('imagify-success-viewing');
				imagifyModal.$modal.attr('aria-labelledby', 'imagify-success-view');
			} else {
				$modalContent.removeClass('imagify-success-viewing');
				imagifyModal.$modal.removeAttr('aria-labelledby');
			}

			$view.fadeIn(imagifyModal.speedFadeIn).attr('aria-hidden', 'false');
		},

		/**
		 * @uses imagifyModal.getApiKey()
		 */
		iframeSetSrc: function (params) {
			/**
			 * params = {
			 *     'monthly': {
			 *         'lite': {
			 *             name: 'something',
			 *             id: ''
			 *         }
			 *     },
			 *     'onetime': {
			 *         'recommended': {
			 *             name: 'Recommend',
			 *             id: ''
			 *         }
			 *     },
			 *     'period': 'monthly'|'yearly'
			 * }
			 */

			var $iframe = $('#imagify-payment-iframe'),
				iframe_src = $iframe.attr('src'),
				pay_src = $iframe.data('src'),
				monthly_id = 0,
				onetime_id = 0,
				// Stop it ESLint, you're drunk.
				key, amount, // eslint-disable-line no-unused-vars
				rt_onetime, rt_yearly, rt_monthly, coupon, rt_coupon, $iframeClone, tofind;

			// If we only change monthly/yearly payment mode.
			if (typeof params === 'string' && '' !== iframe_src) {
				tofind = 'monthly' === params ? 'yearly' : 'monthly';
				iframe_src = iframe_src.replace(tofind, params);
				$iframe.attr('src', iframe_src);
				return;
			}

			// If we get new informations about products.
			if (typeof params !== 'object') {
				return;
			}

			if (params.monthly) {
				monthly_id = params.monthly[Object.keys(params.monthly)[0]].id;
			}

			if (params.onetime) {
				onetime_id = params.onetime[Object.keys(params.onetime)[0]].id;
				// If onetime ID === 999 it's a custom plan, send datas instead.
				onetime_id = (onetime_id + '' === '999' ? params.onetime[Object.keys(params.onetime)[0]].data : onetime_id);
			}

			if (! params.period) {
				w.imagify.info('No period defined');
				return;
			}

			rt_onetime = onetime_id;
			rt_yearly = 'yearly' === params.period ? monthly_id : 0;
			rt_monthly = 'monthly' === params.period ? monthly_id : 0;
			coupon = $('#imagify-coupon-code').val();
			rt_coupon = '' === coupon ? 'none' : coupon;

			// Compose route.
			// pay_src + :ontimeplan(0)/:monthlyplan(0)/:yearlyplan(0)/:coupon(none)/
			pay_src = pay_src + rt_onetime + '/' + rt_monthly + '/' + rt_yearly + '/' + rt_coupon + '/';

			// iFrame sort of cache fix.
			$iframeClone = $iframe.remove().attr('src', pay_src);

			imagifyModal.$paymentView.html($iframeClone);
		},

		/**
		 * Public function triggered by payement iframe.
		 */
		paymentClose: function () {
			$('.imagify-iframe-viewing .close-btn').trigger('click.imagify');
			$('.imagify-iframe-viewing').removeClass('imagify-iframe-viewing');
		},

		/**
		 * @uses imagifyModal.switchToView()
		 */
		paymentBack: function () {
			imagifyModal.switchToView(imagifyModal.$preView);
		},

		/**
		 * @uses imagifyModal.switchToView()
		 */
		paymentSuccess: function () {
			imagifyModal.switchToView(imagifyModal.$successView);
		},

		/**
		 * @uses imagifyModal.paymentClose()
		 * @uses imagifyModal.paymentBack()
		 * @uses imagifyModal.paymentSuccess()
		 */
		checkPluginMessage: function (e) {
			var origin = e.origin || e.originalEvent.origin; // eslint-disable-line no-shadow

			if ( imagifyPricingModal.imagify_app_domain !== origin ) {
				return;
			}

			switch (e.data) {
				case 'cancel':
					imagifyModal.paymentClose();
					break;
				case 'back':
					imagifyModal.paymentBack();
					break;
				case 'success':
					imagifyModal.paymentSuccess();
					break;
			}
		},
		getPromoAppliesTo: function(promo){
			var applies_to = [];
			if (promo.applies_to instanceof Array) {
				var plan_list = [];

				for (var plan_infos = 0; plan_infos < promo.applies_to.length; plan_infos++) {
					plan_list.push(promo.applies_to[plan_infos].plan_name);
				}

				plan_list.forEach(function (item) {
					if (! applies_to.includes(item)) {
						applies_to.push(item);
					}
				});
			} else {
				applies_to = [promo.applies_to];
			}
			return applies_to;
		}
	};

	/**
	 * INIT.
	 */

	// Check all boxes on load.
	imagifyModal.checkCheckbox(imagifyModal.$checkboxes);
	imagifyModal.checkRadio(imagifyModal.$radios.filter(':checked'));

	// Check coupon onload.
	imagifyModal.checkCoupon();

	// Check the changed box.
	imagifyModal.$checkboxes.on('change.imagify', function () {
		imagifyModal.checkCheckbox($(this));
	});

	// Check the radio box.
	imagifyModal.$radios.on('change.imagify', function () {
		imagifyModal.checkRadio($(this));
	});

	/**
	 * Get pricings on modal opening.
	 * Build the pricing tables inside modal.
	 */
	$('#imagify-get-pricing-modal').on('click.imagify-ajax', function () {
		imagifyModal.getPricing($(this));
	});

	/**
	 * Reset the modal on close.
	 */
	$(d).on('modalClosed.imagify', '.imagify-payment-modal', function () {
		// Reset viewing class & aria-labelledby.
		$('#imagify-coupon-code').val('');

		$(this).find('.imagify-modal-content').removeClass('imagify-success-viewing imagify-iframe-viewing');

		// Reset first view after fadeout ~= 300 ms.
		setTimeout(function () {
			$('.imagify-modal-views').hide();
			$('#imagify-pre-checkout-view').show();
		}, 300);

		//delay scrolltop top to avoid flickering
		setTimeout(function () {
			$('.imagify-payment-modal').find('.imagify-modal-content').scrollTop(0);
		}, 400);
	});

	/**
	 * Get validation for Coupon Code
	 * - On blur
	 * - On Enter or Spacebar press
	 * - On click OK button
	 *
	 * @since 1.6.3 Only if field hasn't readonly attribute (discount auto-applied).
	 */
	$('#imagify-coupon-code').on('blur.imagify', function () {
		if (! $(this).attr('readonly')) {
			imagifyModal.checkCoupon();
		}
	}).on('keydown.imagify', function (e) {
		var $this = $(this);

		if ($this.attr('readonly')) {
			return;
		}
		if (13 === e.keyCode || 32 === e.keyCode) {
			imagifyModal.checkCoupon();
			return false;
		}
		if ($this.val().length >= 3) {
			$this.closest('.imagify-coupon-input').addClass('imagify-canbe-validate');
		} else {
			$this.closest('.imagify-coupon-input').removeClass('imagify-canbe-validate');
		}
	});

	$('#imagify-coupon-validate').on('click.imagify', function () {
		imagifyModal.checkCoupon();
		$(this).closest('.imagify-canbe-validate').removeClass('imagify-canbe-validate');
	});

	/**
	 * View game, step by step.
	 */

	// 1) when you decide to choose another plan.

	/**
	 * 1.a) on click, display choices.
	 *
	 * @uses imagifyModal.switchToView()
	 */
	imagifyModal.$anotherBtn.on('click.imagify', function (e) {
		var type = $(this).data('imagify-choose'),
			tab = 'imagify-pricing-tab-' + ('plan' === type ? 'monthly' : 'onetime');

		e.preventDefault();

		imagifyModal.switchToView(imagifyModal.$plansView, {tab: tab});
	});

	/**
	 * 1.b) on click in a choice, return to pre-checkout step.
	 *
	 * @uses imagifyModal.getHtmlPrice()
	 * @uses imagifyModal.switchToView()
	 * @uses imagifyModal.populatePayBtn()
	 */
	imagifyModal.$modal.on('click.imagify', '.imagify-payment-btn-select-plan', function (e) {
		var $_this = $(this),
			$offer_line = $_this.closest('.imagify-offer-line'),
			datas = $_this.data('offer'),
			datas_str = $_this.attr('data-offer'),
			is_onetime = $_this.closest('.imagify-tab-content').attr('id') !== 'imagify-pricing-tab-monthly',
			$target_line = is_onetime ? imagifyModal.$preView.find('.imagify-offer-onetime') : imagifyModal.$preView.find('.imagify-offer-monthly'),
			period = is_onetime ? null : ($_this.closest('.imagify-pricing-table').hasClass('imagify-month-selected') ? 'monthly' : 'yearly'),
			price = is_onetime ? imagifyModal.getHtmlPrice(datas[Object.keys(datas)[0]].price) : imagifyModal.getHtmlPrice(datas[Object.keys(datas)[0]].prices, period),
			monthly_txt = is_onetime ? '' : '<span class="imagify-price-by">' + $offer_line.find('.imagify-price-by').text() + '</span>',
			discount = $offer_line.find('.imagify-price-discount').html(),
			imgs = $offer_line.find('.imagify-approx-nb').text(),
			offer_size = $offer_line.find('.imagify-offer-size').text(),
			$coupon_input = $('#imagify-coupon-code');

		e.preventDefault();

		// Change views to go back pre-checkout.
		imagifyModal.switchToView(imagifyModal.$preView);

		// Change price (+ "/month" if found in monthly plans).
		$target_line.find('.imagify-number-block').html(price + monthly_txt);

		// Change discount.
		if (discount) {
			if ($target_line.find('.imagify-price-discount').length <= 0) {
				$target_line.find('.imagify-col-price').prepend('<span class="imagify-price-discount"></span>');
			}
			$target_line.find('.imagify-price-discount').html(discount);
			$target_line.find('.imagify-price-discount').show();
		} else {
			$target_line.find('.imagify-price-discount').hide();
		}

		// Change approx images nb.
		$target_line.find('.imagify-approx-nb').text(imgs);

		// Change offer size name.
		$target_line.find('.imagify-offer-size').text(offer_size);

		// Change datas (json).
		$target_line.attr('data-offer', datas_str);

		if (! is_onetime) {
			$target_line.find('.imagify-price-add-data').text($offer_line.find('.imagify-price-add-data').text());

			// Trigger period selected from offer selection view to pre-checkout view.
			if ('monthly' === period) {
				$target_line.find('#imagify-subscription-monthly').trigger('click.imagify');
			} else {
				$target_line.find('#imagify-subscription-yearly').trigger('click.imagify');
			}
			$target_line.find('.imagify-inline-options').find('input:radio:checked').trigger('change.imagify');
		}

		$coupon_input = $('#imagify-coupon-code');
		$coupon_input.val('');

		if ( w.imagify_discount_datas ){
			var applies_to = imagifyModal.getPromoAppliesTo(w.imagify_discount_datas);
			if ( applies_to.includes(datas[Object.keys(datas)[0]].label ) || "all" === applies_to[0] ){
				$coupon_input.val(w.imagify_discount_datas.label);
			}
		}

		imagifyModal.checkCoupon();

		// Update price information in button.
		imagifyModal.populatePayBtn();
	});

	/**
	 * 2) when you checkout.
	 *
	 * @uses imagifyModal.switchToView()
	 * @uses imagifyModal.getPeriod()
	 * @uses imagifyModal.iframeSetSrc()
	 */
	$('#imagify-modal-checkout-btn').on('click.imagify', function (e) {
		var $monthly_offer, $onetime_offer, checkout_datas;

		e.preventDefault();

		// Do nothing if button disabled.
		if ($(this).hasClass('imagify-button-disabled')) {
			return;
		}

		$monthly_offer = $('.imagify-offer-monthly');
		$onetime_offer = $('.imagify-offer-onetime');
		checkout_datas = {};

		// If user choose a monthly plan.
		if ($monthly_offer.hasClass('imagify-offer-selected')) {
			checkout_datas.monthly = JSON.parse($monthly_offer.attr('data-offer'));
		}

		// If user choose a One Time plan.
		if ($onetime_offer.hasClass('imagify-offer-selected')) {
			checkout_datas.onetime = JSON.parse($onetime_offer.attr('data-offer'));
		}

		// Clear user account cache.
		if (imagifyPricingModal.userDataCache) {
			$.post(ajaxurl, {
				action:   imagifyPricingModal.userDataCache.deleteAction,
				_wpnonce: imagifyPricingModal.userDataCache.deleteNonce
			});
		}

		// Change views to go to checkout/payment view.
		imagifyModal.switchToView(imagifyModal.$paymentView);

		checkout_datas.period = imagifyModal.getPeriod();
		imagifyModal.iframeSetSrc(checkout_datas);
	});

	/**
	 * Go back to previous step ("Choose Another Plan" links).
	 */
	$('.imagify-back-to-plans').on('click.imagify', function (e) {
		var $_this = $(this),
			is_onetime = $_this.closest('.imagify-cart-item').hasClass('imagify-cart-item-onetime');

		e.preventDefault();

		if (is_onetime) {
			$('.imagify-offer-onetime').find('.imagify-choose-another-plan').trigger('click.imagify');
		} else {
			$('.imagify-offer-monthly').find('.imagify-choose-another-plan').trigger('click.imagify');
		}
	});

	// Message/communication API.
	w.addEventListener('message', imagifyModal.checkPluginMessage, true);

})(jQuery, document, window);
