function initSplitItPaymentBlocks( props, isCreateAccountChecked, isShipToDifferentAddressChecked, orderNotes ) {
	(function ($) {
		"use strict";

		if (typeof wp !== 'undefined' && wp.data) {
			const { subscribe, select } = wp.data;

			subscribe(() => {
				try {
					const cartStore = select('wc/store/cart');

					if (cartStore && cartStore.getCustomerData) {
						const currentAddressData = cartStore.getCustomerData();
						if (currentAddressData) {
							window.splititCurrentAddressData = currentAddressData;
						}
					}
				} catch (e) {
					console.warn("splitit subscribe error", e);
				}
			});
		}

		let billingData  = props.billing.billingAddress;
		let shippingData = props.shippingData.shippingAddress;

		let checkoutFormData = {};

		let orderId  = null;
		let debug3ds = false;
		let culture  = 'en-US';

		if ('undefined' !== typeof splititPaymentData) {
			const urlParams = new URLSearchParams( window.location.search );
			orderId         = urlParams.get( 'order-pay' );
			debug3ds        = splititPaymentData.debug3ds;
			culture         = splititPaymentData.culture;
		} else {
			console.log( 'splititPaymentData Error: No Splitit Payment Data' );
			return;
		}

		$( '#radio-control-wc-payment-method-options-splitit' ).change(
			function () {
				if ($( this ).is( ':checked' )) {
					$( 'body' ).trigger( 'update_checkout' );
				}
			}
		)

		localStorage.setItem( 'flex_fields_success', 'false' );
		localStorage.setItem( 'flex_fields_error', 'false' );
		localStorage.setItem( 'checkout_form_data', 'null' );

		if ( window.isSplititPaymentFormInited ) {
			return; // do not init it couple times (for example, WooCommerce Smart COD plugin reinit form)
		}

		$( document ).ready(
			function () {
				if ( 'undefined' === typeof flexFieldsInstance ) {
					  firstInitFlexFieldsInstanceBlocks();
				} else {
					$( document ).trigger( 'update_checkout' );
				}
			}
		);

		$( 'body' ).on(
			'update_checkout' ,
			function () {
				let ipn = localStorage.getItem( 'ipn' ) ?? false;

				if ( isSplititPaymentSelectedBlocks() ) {
					if ( 'undefined' === typeof flexFieldsInstance ) {
						cleanupWoocommerceErrorMessageBlocks();
						$( '#custom_splitit_error' ).remove();
						firstInitFlexFieldsInstanceBlocks();
					} else if ( ipn ) {
						updateFlexFieldsTotalBlocks( ipn );
					}
				}
			}
		);

		$( '.wc-block-checkout__form' ).on(
			'change',
			'input[name^="radio-control-wc-payment-method-options"]',
			function () {
				cleanupWoocommerceErrorMessageBlocks();
			}
		);

		window.hideSplititLoaderBlocks = function() {
			$( ".wc-block-components-checkout-place-order-button" ).removeAttr( 'disabled' );
		}

		window.removeLoaderBlocks = function () {
			setTimeout( () => $( '#order_review' ).unblock(), 1000 );
		};

		window.addSplititErrorMessageBlocks = function ( errorMessage ) {
			localStorage.setItem( 'flex_fields_error', errorMessage );
			if ( ! $( '#custom_splitit_error' ).length ) {
				$( '.payment_method_splitit' ).prepend( '<p id="custom_splitit_error" style="color:red;">' + errorMessage + '</p>' );
			}
		};

		window.addWoocommerceErrorMessageBlocks = function ( errorMessage, form ) {
			cleanupWoocommerceErrorMessageBlocks();
			localStorage.setItem( 'flex_fields_error', errorMessage );

			$( form ).prepend( '<ul class="woocommerce-error">' + errorMessage + '</ul>' );
		};

		window.cleanupWoocommerceErrorMessageBlocks = function () {
			localStorage.setItem( 'flex_fields_error', 'false' );
			$( '.woocommerce-error' ).remove();
		};

		window.scrollTopToBlock = function ( block ) {
			var $block = $( block );

			if ( $block.length ) {
				$('html, body').animate(
					{
						scrollTop: ( $block.offset().top - 100 )
					},
					1000
				);
			} else {
				console.warn('scrollTopToBlock: Element not found', block);
			}
		}

		function collectSplititBillingPayloadBlocks() {
			const billingAddressCurrentData = (window.splititCurrentAddressData && window.splititCurrentAddressData.billingAddress)
				? window.splititCurrentAddressData.billingAddress
				: props.billing.billingAddress;

			return {
				billingAddress: {
					AddressLine: billingAddressCurrentData.address_1,
					AddressLine2: billingAddressCurrentData.address_2,
					City: getBillingAddressValueBlocks('city', billingAddressCurrentData),
					State: billingAddressCurrentData.state,
					Country: billingAddressCurrentData.country,
					Zip: getBillingAddressValueBlocks('postcode', billingAddressCurrentData)
				},
				consumerData: {
					FullName: billingAddressCurrentData.first_name + ' ' + billingAddressCurrentData.last_name,
					Email: billingAddressCurrentData.email,
					PhoneNumber: billingAddressCurrentData.phone,
					CultureName: culture
				}
			};
		}

		window.getBillingAddressValueBlocks = function (code, billingDataUpdated) {
			// In some cases city or state is optional, but it required in Splitit
			let value = billingDataUpdated[code];
			if ( ! value || '' === value) {
				value = billingDataUpdated.address_2;
			}
			if ( ! value || '' === value) {
				value = billingDataUpdated.address_1;
			}
			if ( ! value || '' === value) {
				value = billingDataUpdated.country;
			}
			if ( ! value || '' === value) {
				value = billingDataUpdated.postcode;
			}
			return value;
		}

		window.setErrorBlocks = function (text) {
			var form       = $( 'form.wc-block-checkout__form' );
			var errMessage = "<li>" + text + "</li>";
			addWoocommerceErrorMessageBlocks( errMessage, form );
			scrollTopToBlockBlocks( 'form.wc-block-checkout__form' );
			hideSplititLoaderBlocks();
		}

		window.checkPhoneNumberBlocks = function () {
			var isValidBillingPhone = true;
			if ( 'undefined' != typeof intlTelInputGlobals ) {
				var billingPhoneInput = document.querySelector( "#billing_phone" );
				if (billingPhoneInput) {
					var iti = Object.values( window.intlTelInputGlobals.instances ).find( i => i.a === billingPhoneInput );
					if ('undefined' != typeof iti) {
						isValidBillingPhone = iti.isValidNumber();
					}
				}
			}
			return isValidBillingPhone;
		}

		window.performPaymentBlocks = function (propsUpdated, isCreateAccountCheckedUpdated, isShipToDifferentAddressCheckedUpdated, orderNotesUpdated) {
			if ( ! isSplititPaymentSelectedBlocks() ) {
				return;
			}

			if ( ! flexFieldsInstance.isValid() ) {
				flexFieldsInstance.updateTermsSigned();
			}

			let billingDataUpdated  = propsUpdated.billing.billingAddress;
			let shippingDataUpdated = propsUpdated.shippingData.shippingAddress;

			$( '.wc-block-components-checkout-place-order-button' ).attr( 'disabled', true );

			if ( debug3ds ) {
				setTimeout( function() { hideSplititLoaderBlocks() }, 2000 );
			}

			flexFieldsInstance.triggerValidation();

			flexFieldsInstance.updateDetails(
				{
					billingAddress: {
						addressLine: billingDataUpdated.address_1,
						addressLine2: billingDataUpdated.address_2,
						city: getBillingAddressValueBlocks( 'city', billingDataUpdated ),
						state: billingDataUpdated.state,
						country: billingDataUpdated.country,
						zip: getBillingAddressValueBlocks( 'postcode', billingDataUpdated )
					},
					consumerData: {
						fullName: billingDataUpdated.first_name + ' ' + billingDataUpdated.last_name,
						email: billingDataUpdated.email,
						phoneNumber: billingDataUpdated.phone,
						cultureName: culture
					}
				}
			);

			checkoutFormData['payment_method'] = propsUpdated.activePaymentMethod;
			checkoutFormData['order_comments'] = orderNotesUpdated;
			$.each(
				billingDataUpdated,
				function (name, value) {
					checkoutFormData['billing_' + name] = value;
				}
			);
			$.each(
				shippingDataUpdated,
				function (name, value) {
					checkoutFormData['shipping_' + name] = value;
				}
			);
			if (isCreateAccountCheckedUpdated) {
				checkoutFormData['createaccount'] = '1';
			}
			if ( ! isShipToDifferentAddressCheckedUpdated) {
				checkoutFormData['ship_to_different_address'] = '1';
			}

			$.ajax(
				{
					url: getSplititAjaxURL( 'checkout_validate' ),
					method: 'POST',
					dataType: 'json',
					async: false,
					data: {
						action: 'checkout_validate',
						fields: checkoutFormData,
						ipn: localStorage.getItem( 'ipn' )
					},
					success: function ( data ) {
						if ( 'success' == data.result ) {
							cleanupWoocommerceErrorMessageBlocks();

							$( '.wc-block-components-checkout-place-order-button' ).attr( 'disabled', true );

							// Check if flex fields has errors.
							if ( ! flexFieldsInstance.isValid() ) {
								flexFieldsInstance.triggerValidation()
								console.log( 'flexFieldsInstance: ', 'flex form is not valid' );
								hideSplititLoaderBlocks();
								localStorage.setItem( 'flex_fields_error', 'Please check your input' );

								return false;
							} else {
								if (window.location.href.includes( "hobfurniture" ) || window.location.href.includes( "bioflexwave" ) || window.location.href.includes( "camelliarts" )) {
									flexFieldsInstance.pay();
								} else {
									if ( 'undefined' == typeof grecaptcha || ( 'undefined' != typeof grecaptcha && "" != grecaptcha.getResponse() ) ) {
										if ($( 'input[name="cf-turnstile-response"]' ).length) {
											if ('' != $( 'input[name="cf-turnstile-response"]' ).val()) {
												if (checkPhoneNumberBlocks()) {
													flexFieldsInstance.pay();
												} else {
													setError( 'Phone is not a valid phone number.' );
												}
											} else {
												setError( 'Verify you are human is a required field.' );
											}
										} else {
											if (checkPhoneNumberBlocks()) {
												flexFieldsInstance.pay();
											} else {
												setError( 'Phone is not a valid phone number.' );
											}
										}
									} else {
										setError( 'I`m not a robot is a required field.' );
									}
								}
							}
						} else {
							let $form        = $( 'form.wc-block-checkout__form' );
							let errorMessage = data.messages ? data.messages : data;

							$form.find( '.input-text, select' ).blur();

							addWoocommerceErrorMessageBlocks( errorMessage, $form );
							scrollTopToBlockBlocks( 'form.wc-block-checkout__form' );
							hideSplititLoaderBlocks();
						}
					},
					error: function ( error ) {
						localStorage.setItem( 'flex_fields_error', error );
						scrollTopToBlockBlocks( 'form.wc-block-checkout__form' );
						hideSplititLoaderBlocks();
					}
				}
			);

			// this is necessary to track the event of closing the 3D Secure modal window.
			const modalContainer = document.body;

			const observer = new MutationObserver(
				function(mutations) {
					mutations.forEach(
						function(mutation) {
							const closeButtons = modalContainer.querySelectorAll( '.close-btn' );

							closeButtons.forEach(
								closeButton => {
									if ( ! closeButton.dataset.listenerAdded) {
										closeButton.dataset.listenerAdded = 'true';
										closeButton.addEventListener(
										'click',
										function(event) {
											const modalOverlay = closeButton.closest( '.spt-overlay' );
											if (modalOverlay) {
												localStorage.setItem( 'flex_fields_error', '' );
											}
										}
										);
									}
								}
							);
						}
					);
				}
			);

			modalContainer.addEventListener(
				'click',
				function(event) {
					if (event.target.classList.contains( 'spt-overlay' )) {
						localStorage.setItem( 'flex_fields_error', '' );
					}
				}
			);

			observer.observe(
				modalContainer,
				{
					childList: true,
					subtree: true
				}
			);
		}

		window.firstInitFlexFieldsInstanceBlocks = function() {
			const billingPayload = collectSplititBillingPayloadBlocks();

			$.ajax(
				{
					url: getSplititAjaxURL( 'flex_field_initiate_method' ),
					method: 'POST',
					dataType: 'json',
					data: {
						action: 'flex_field_initiate_method',
						order_id: orderId,
						numberOfInstallments: '',
						currency: getCurrencyCodeBlocks(),
						billing: JSON.stringify(billingPayload)
					},
					success: function ( data ) {
						if ( 'undefined' == typeof data || 'undefined' == typeof data.installmentPlanNumber ) {
							if ( isSplititPaymentSelectedBlocks() ) {
								let form = $( '.wc-block-checkout__form' ).length ? '.wc-block-checkout__form' : '#order_review';
								addWoocommerceErrorMessageBlocks( data.error.message, form );
							}

							addSplititErrorMessageBlocks( data.error.message );
							removeLoaderBlocks();
						} else {
							localStorage.setItem( 'ipn', data.installmentPlanNumber );
							initFlexFieldsInstanceBlocks( data )
						}

						// compatibility with some themes (empty fields in form)
						setTimeout( function(){window.dispatchEvent( new Event( 'resize' ) );}, 100 );
						hideSplititLoaderBlocks();
					},
					error: function ( error ) {
						console.log( error.responseText );
						removeLoaderBlocks();
						hideSplititLoaderBlocks();
					}
				}
			);
		}

		window.initFlexFieldsInstanceBlocks = function( data ) {
			if ( ! data.shopper.fullName && billingData.first_name && billingData.last_name ) {
				data.shopper.fullName = billingData.first_name + ' ' + billingData.last_name;
			}

			flexFieldsInstance = window.Splitit.FlexForm.setup(
				{
					showOnReady: true,
					nameField: {
						hide: true
					},
					culture: culture,
					ipn: data.installmentPlanNumber,
					container: "flex-form",
					numberOfInstallments: data.numberOfInstallments,
					billingAddress: data.billingAddress,
					consumerData: data.shopper,
					paymentButton: {
						isCustom: true
					},
					onSuccess( data ) {
						// simulate error process for debug async flow
						if ('simulateError' === window.splititAsyncDebug) {
							console.log( "planNumber: " + flexFieldsInstance.ipn );
							return;
						}

						checkoutFormData['flex_field_ipn']         = flexFieldsInstance.ipn;
						checkoutFormData['flex_field_num_of_inst'] = flexFieldsInstance.getSelectedNumInstallments();

						// Set item in local storage for inform about flex fields paid successfully
						localStorage.setItem( 'flex_fields_success', 'true' );
						localStorage.setItem( 'checkout_form_data', JSON.stringify( checkoutFormData ) );
					},
					onError( result ) {
						console.log( 'onError:', result );

						localStorage.setItem( 'flex_fields_success', 'false' );
						localStorage.setItem( 'flex_fields_error', result.Message );
						removeLoaderBlocks();
						hideSplititLoaderBlocks();
					},
					onEvent( ev ) {
						if ( "modal3ds" == ev.component && "change" == ev.evType && "closed" == ev.newValue ) {
							localStorage.setItem( 'flex_fields_error', '' );
							hideSplititLoaderBlocks();
						}
					}
				}
			).ready(
				function (manage) {
					console.log( '🚀 ~ READY CALLBACK', manage );
				}
			);
		}

		window.updateFlexFieldsTotalBlocks = function( planNumber ) {
			if ( undefined !== flexFieldsInstance ) {
				const billingPayload = collectSplititBillingPayloadBlocks();

				$.ajax(
					{
						url: getSplititAjaxURL( 'flex_field_initiate_method' ),
						data: {
							'action': 'flex_field_initiate_method',
							'ipn': planNumber,
							'order_id': orderId,
							'numberOfInstallments': '',
							'function': 'updateFlexFieldsTotal',
							'currency': getCurrencyCodeBlocks(),
							'billing': JSON.stringify(billingPayload)
						},
						method: "POST",
						dataType: 'json',
						success: function ( data ) {
							cleanupWoocommerceErrorMessageBlocks();
							$( '#custom_splitit_error' ).remove();
							if ( 'undefined' != typeof data.error ) {
								flexFieldsInstance.hide();
								addSplititErrorMessageBlocks( data.error.message );
							} else {
								localStorage.setItem( 'ipn', data.installmentPlanNumber );
								initFlexFieldsInstanceBlocks( data )
							}

							hideSplititLoaderBlocks();
						},
						error: function ( error ) {
							console.log( '~ updateFlexFieldsTotal error: ', error );
							hideSplititLoaderBlocks();
						}
					}
				);
			}
		}

		window.getCurrencyCodeBlocks = function() {
			// compatibility with WooCommerce Multilingual plugin
			if ('undefined' != typeof wcml_mc_settings) {
				return wcml_mc_settings.current_currency.code;
			}
			return '';
		}

		window.isSplititPaymentSelectedBlocks = function() {
			return $( '#radio-control-wc-payment-method-options-splitit' ).is( ':checked' );
		}

		// compatibility with some themes (empty fields in form)
		$( document.body ).off( "payment_method_selected" );
		$( document.body ).on(
			"payment_method_selected",
			function() {
				$( 'body' ).trigger( 'update_checkout' );
				if (isSplititPaymentSelectedBlocks()) {
					window.dispatchEvent( new Event( 'resize' ) );
				}
			}
		);

		function debounce(func, delay) {
			let timeout;
			return function(...args) {
				clearTimeout( timeout );
				timeout = setTimeout( () => func.apply( this, args ), delay );
			};
		}

		if (isSplititPaymentSelectedBlocks()) {
			$( '.wc-block-checkout__form' ).on(
				'input',
				'input, select, textarea',
				debounce(
					function(event) {
						const target = event.target;

						const isRelevantField = target.id.includes( 'email' ) ||
						target.id.includes( 'coupon' ) ||
						target.id.includes( 'first_name' ) ||
						target.id.includes( 'last_name' ) ||
						target.id.includes( 'country' ) ||
						target.id.includes( 'address' ) ||
						target.id.includes( 'city' ) ||
						target.id.includes( 'state' ) ||
						target.id.includes( 'postcode' ) ||
						target.id.includes( 'flat_rate' ) ||
						target.id.includes( 'phone' );

						if (isRelevantField) {
							$( document.body ).trigger( 'update_checkout' )
						}
					},
					1000
				)
			);
		}

		if ('undefined' !== typeof wc && wc.wcSettings && wp.data) {
			const { select, subscribe } = wp.data;
			const previousTotals		= select( 'wc/store/cart' ).getCartTotals();
			let previousTotal           = previousTotals ? previousTotals.total_price : null;

			const unsubscribe           = subscribe(
				() => {
					const currentTotals = select( 'wc/store/cart' ).getCartTotals();
					const currentTotal  = currentTotals ? currentTotals.total_price : null;
					if ( currentTotal !== previousTotal ) {
						previousTotal = currentTotal;
						$( document.body ).trigger( 'update_checkout' );
					}
				}
			);

			window.addEventListener( 'beforeunload', unsubscribe );
		}

		window.isSplititPaymentFormInited = true;
	})( jQuery );
}
