/* global jpSimplePaymentsStrings */
/* eslint no-var: 0, quote-props: 0 */

( function ( api, wp, $ ) {
	var $document = $( document );

	$document.ready( function () {
		$document.on( 'widget-added', function ( event, widgetContainer ) {
			if ( widgetContainer.is( '[id*="jetpack_simple_payments_widget"]' ) ) {
				initWidget( widgetContainer );
			}
		} );

		$document.on( 'widget-synced widget-updated', function ( event, widgetContainer ) {
			//this fires for all widgets, this prevent errors for non SP widgets
			if ( ! widgetContainer.is( '[id*="jetpack_simple_payments_widget"]' ) ) {
				return;
			}

			event.preventDefault();

			syncProductLists();

			var widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' );

			enableFormActions( widgetForm );

			updateProductImage( widgetForm );
		} );
	} );

	function initWidget( widgetContainer ) {
		var widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' );

		//Add New Button
		widgetForm
			.find( '.jetpack-simple-payments-add-product' )
			.on( 'click', showAddNewForm( widgetForm ) );
		//Edit Button
		widgetForm
			.find( '.jetpack-simple-payments-edit-product' )
			.on( 'click', showEditForm( widgetForm ) );
		//Select an Image
		widgetForm
			.find(
				'.jetpack-simple-payments-image-fieldset .placeholder, .jetpack-simple-payments-image > img'
			)
			.on( 'click', selectImage( widgetForm ) );
		//Remove Image Button
		widgetForm
			.find( '.jetpack-simple-payments-remove-image' )
			.on( 'click', removeImage( widgetForm ) );
		//Save Product button
		widgetForm
			.find( '.jetpack-simple-payments-save-product' )
			.on( 'click', saveChanges( widgetForm ) );
		//Cancel Button
		widgetForm
			.find( '.jetpack-simple-payments-cancel-form' )
			.on( 'click', clearForm( widgetForm ) );
		//Delete Selected Product
		widgetForm
			.find( '.jetpack-simple-payments-delete-product' )
			.on( 'click', deleteProduct( widgetForm ) );
		//Input, Select and Checkbox change
		widgetForm.find( 'select, input, textarea, checkbox' ).on(
			'change input propertychange',
			_.debounce( function () {
				disableFormActions( widgetForm );
			}, 250 )
		);
	}

	function syncProductLists() {
		var request = wp.ajax.post( 'customize-jetpack-simple-payments-buttons-get', {
			'customize-jetpack-simple-payments-nonce':
				api.settings.nonce[ 'customize-jetpack-simple-payments' ],
			customize_changeset_uuid: api.settings.changeset.uuid,
		} );

		request.done( function ( data ) {
			var selectedProduct = 0;

			$( document )
				.find( 'select.jetpack-simple-payments-products' )
				.each( function ( index, select ) {
					var $select = $( select );
					selectedProduct = $select.val();

					$select.find( 'option' ).remove();
					$select.append(
						$.map( data, function ( product ) {
							return $( '<option>', { value: product.ID, text: product.post_title } );
						} )
					);
					$select.val( selectedProduct );
				} );
		} );
	}

	function showForm( widgetForm ) {
		//reset validations
		widgetForm.find( '.invalid' ).removeClass( 'invalid' );
		//disable widget title and product selector
		widgetForm
			.find( '.jetpack-simple-payments-widget-title' )
			.add( '.jetpack-simple-payments-products' )
			//disable add and edit buttons
			.add( '.jetpack-simple-payments-add-product' )
			.add( '.jetpack-simple-payments-edit-product' )
			//disable save, delete and cancel until the widget update event is fired
			.add( '.jetpack-simple-payments-save-product' )
			.add( '.jetpack-simple-payments-cancel-form' )
			.add( '.jetpack-simple-payments-delete-product' )
			.attr( 'disabled', 'disabled' );
		//show form
		widgetForm.find( '.jetpack-simple-payments-form' ).show();
	}

	function hideForm( widgetForm ) {
		//enable widget title and product selector
		widgetForm
			.find( '.jetpack-simple-payments-widget-title' )
			.add( '.jetpack-simple-payments-products' )
			.removeAttr( 'disabled' );
		//hide the form
		widgetForm.find( '.jetpack-simple-payments-form' ).hide();
	}

	function changeFormAction( widgetForm, action ) {
		widgetForm.find( '.jetpack-simple-payments-form-action' ).val( action ).change();
	}

	function showAddNewForm( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			showForm( widgetForm );
			changeFormAction( widgetForm, 'add' );
		};
	}

	function showEditForm( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			showForm( widgetForm );
			changeFormAction( widgetForm, 'edit' );
		};
	}

	function clearForm( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			hideForm( widgetForm );
			widgetForm
				.find( '.jetpack-simple-payments-add-product, .jetpack-simple-payments-edit-product' )
				.attr( 'disabled', 'disabled' );
			changeFormAction( widgetForm, 'clear' );
		};
	}

	function enableFormActions( widgetForm ) {
		var isFormVisible = widgetForm.find( '.jetpack-simple-payments-form' ).is( ':visible' );
		var isProductSelectVisible = widgetForm
			.find( '.jetpack-simple-payments-products' )
			.is( ':visible' ); //areProductsVisible ?
		var isEdit = widgetForm.find( '.jetpack-simple-payments-form-action' ).val() === 'edit';

		if ( isFormVisible ) {
			widgetForm
				.find( '.jetpack-simple-payments-save-product' )
				.add( '.jetpack-simple-payments-cancel-form' )
				.removeAttr( 'disabled' );
		} else {
			widgetForm.find( '.jetpack-simple-payments-add-product' ).removeAttr( 'disabled' );
		}

		if ( isFormVisible && isEdit ) {
			widgetForm.find( '.jetpack-simple-payments-delete-product' ).removeAttr( 'disabled' );
		}

		if ( isProductSelectVisible && ! isFormVisible ) {
			widgetForm.find( '.jetpack-simple-payments-edit-product' ).removeAttr( 'disabled' );
		}
	}

	function disableFormActions( widgetForm ) {
		widgetForm
			.find( '.jetpack-simple-payments-add-product' )
			.add( '.jetpack-simple-payments-edit-product' )
			.add( '.jetpack-simple-payments-save-product' )
			.add( '.jetpack-simple-payments-cancel-form' )
			.add( '.jetpack-simple-payments-delete-product' )
			.attr( 'disabled', 'disabled' );
	}

	function selectImage( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			var imageContainer = widgetForm.find( '.jetpack-simple-payments-image' );

			var mediaFrame = new wp.media.view.MediaFrame.Select( {
				title: 'Choose Product Image',
				multiple: false,
				library: { type: 'image' },
				button: { text: 'Choose Image' },
			} );

			mediaFrame.on( 'select', function () {
				var selection = mediaFrame.state().get( 'selection' ).first().toJSON();
				//hide placeholder
				widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' ).hide();

				//load image from media library
				imageContainer.find( 'img' ).attr( 'src', selection.url ).show();

				//show image and remove button
				widgetForm.find( '.jetpack-simple-payments-image' ).show();

				//set hidden field for the selective refresh
				widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val( selection.id ).change();
			} );

			mediaFrame.open();
		};
	}

	function removeImage( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			//show placeholder
			widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' ).show();

			//hide image and remove button
			widgetForm.find( '.jetpack-simple-payments-image' ).hide();

			//set hidden field for the selective refresh
			widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val( '' ).change();
		};
	}

	function updateProductImage( widgetForm ) {
		var newImageId = parseInt(
			widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val(),
			10
		);
		var newImageSrc = widgetForm.find( '.jetpack-simple-payments-form-image-src' ).val();

		var placeholder = widgetForm.find( '.jetpack-simple-payments-image-fieldset .placeholder' );
		var image = widgetForm.find( '.jetpack-simple-payments-image > img' );
		var imageControls = widgetForm.find( '.jetpack-simple-payments-image' );

		if ( newImageId && newImageSrc ) {
			image.attr( 'src', newImageSrc );
			placeholder.hide();
			imageControls.show();
		} else {
			placeholder.show();
			image.removeAttr( 'src' );
			imageControls.hide();
		}
	}

	function decimalPlaces( number ) {
		var parts = number.split( '.' );
		if ( parts.length > 2 ) {
			return null;
		}

		return parts[ 1 ] ? parts[ 1 ].length : 0;
	}

	function isFormValid( widgetForm ) {
		widgetForm.find( '.invalid' ).removeClass( 'invalid' );

		var errors = false;

		var postTitle = widgetForm.find( '.jetpack-simple-payments-form-product-title' ).val();
		if ( ! postTitle ) {
			widgetForm.find( '.jetpack-simple-payments-form-product-title' ).addClass( 'invalid' );
			errors = true;
		}

		var productPrice = widgetForm.find( '.jetpack-simple-payments-form-product-price' ).val();
		if ( ! productPrice || isNaN( productPrice ) || parseFloat( productPrice ) <= 0 ) {
			widgetForm.find( '.jetpack-simple-payments-form-product-price' ).addClass( 'invalid' );
			errors = true;
		}

		// Japan's Yen is the only supported currency with a zero decimal precision.
		var precision =
			widgetForm.find( '.jetpack-simple-payments-form-product-currency' ).val() === 'JPY' ? 0 : 2;
		var priceDecimalPlaces = decimalPlaces( productPrice );
		if ( priceDecimalPlaces === null || priceDecimalPlaces > precision ) {
			widgetForm.find( '.jetpack-simple-payments-form-product-price' ).addClass( 'invalid' );
			errors = true;
		}

		var productEmail = widgetForm.find( '.jetpack-simple-payments-form-product-email' ).val();
		var isProductEmailValid =
			// eslint-disable-next-line no-control-regex
			/^((([a-z]|\d|[!#$%&'*+\-/=?^_`{|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#$%&'*+\-/=?^_`{|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(
				productEmail
			);
		if ( ! productEmail || ! isProductEmailValid ) {
			widgetForm.find( '.jetpack-simple-payments-form-product-email' ).addClass( 'invalid' );
			errors = true;
		}

		return ! errors;
	}

	function saveChanges( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			if ( ! isFormValid( widgetForm ) ) {
				return;
			}

			var productPostId = widgetForm.find( '.jetpack-simple-payments-form-product-id' ).val();

			disableFormActions( widgetForm );

			widgetForm.find( '.spinner' ).show();

			var request = wp.ajax.post( 'customize-jetpack-simple-payments-button-save', {
				'customize-jetpack-simple-payments-nonce':
					api.settings.nonce[ 'customize-jetpack-simple-payments' ],
				customize_changeset_uuid: api.settings.changeset.uuid,
				params: {
					product_post_id: productPostId,
					post_title: widgetForm.find( '.jetpack-simple-payments-form-product-title' ).val(),
					post_content: widgetForm
						.find( '.jetpack-simple-payments-form-product-description' )
						.val(),
					image_id: widgetForm.find( '.jetpack-simple-payments-form-image-id' ).val(),
					currency: widgetForm.find( '.jetpack-simple-payments-form-product-currency' ).val(),
					price: widgetForm.find( '.jetpack-simple-payments-form-product-price' ).val(),
					multiple: widgetForm
						.find( '.jetpack-simple-payments-form-product-multiple' )
						.is( ':checked' )
						? 1
						: 0,
					email: widgetForm.find( '.jetpack-simple-payments-form-product-email' ).val(),
				},
			} );

			request.done( function ( data ) {
				var select = widgetForm.find( 'select.jetpack-simple-payments-products' );
				var productOption = select.find( 'option[value="' + productPostId + '"]' );

				if ( productOption.length > 0 ) {
					productOption.text( data.product_post_title );
				} else {
					select.append(
						$( '<option>', {
							value: data.product_post_id,
							text: data.product_post_title,
						} )
					);
					select.val( data.product_post_id ).change();
				}

				widgetForm.find( '.jetpack-simple-payments-products-fieldset' ).show();
				widgetForm.find( '.jetpack-simple-payments-products-warning' ).hide();

				changeFormAction( widgetForm, 'clear' );
				hideForm( widgetForm );
			} );

			request.fail( function ( data ) {
				var validCodes = {
					post_title: 'product-title',
					price: 'product-price',
					email: 'product-email',
				};

				data.forEach( function ( item ) {
					if ( Object.hasOwn( validCodes, item.code ) ) {
						widgetForm
							.find( '.jetpack-simple-payments-form-' + validCodes[ item.code ] )
							.addClass( 'invalid' );
					}
				} );

				enableFormActions( widgetForm );
			} );
		};
	}

	function deleteProduct( widgetForm ) {
		return function ( event ) {
			event.preventDefault();

			if ( ! confirm( jpSimplePaymentsStrings.deleteConfirmation ) ) {
				return;
			}

			var formProductId = parseInt(
				widgetForm.find( '.jetpack-simple-payments-form-product-id' ).val(),
				10
			);
			if ( ! formProductId ) {
				return;
			}

			disableFormActions( widgetForm );

			widgetForm.find( '.spinner' ).show();

			var request = wp.ajax.post( 'customize-jetpack-simple-payments-button-delete', {
				'customize-jetpack-simple-payments-nonce':
					api.settings.nonce[ 'customize-jetpack-simple-payments' ],
				customize_changeset_uuid: api.settings.changeset.uuid,
				params: {
					product_post_id: formProductId,
				},
			} );

			request.done( function () {
				var productList = widgetForm.find( 'select.jetpack-simple-payments-products' )[ 0 ];
				productList.remove( productList.selectedIndex );
				productList.dispatchEvent( new Event( 'change' ) );

				if ( $( productList ).has( 'option' ).length === 0 ) {
					//hide products select and label
					widgetForm.find( '.jetpack-simple-payments-products-fieldset' ).hide();
					//show empty products list warning
					widgetForm.find( '.jetpack-simple-payments-products-warning' ).show();
				}

				changeFormAction( widgetForm, 'clear' );
				hideForm( widgetForm );
			} );
		};
	}
} )( wp.customize, wp, jQuery );
