(function( $ ) { 'use strict';
	$( '.mcs_location_fields' ).hide();
	$( '.toggle_location_fields' ).on( 'click', function(e) {
		let change = ( $(this).attr( 'aria-expanded' ) == 'false' ) ? 'true' : 'false';
		let dashicon_old = ( $(this).attr( 'aria-expanded' ) == 'true' ) ? 'dashicons-minus' : 'dashicons-plus';
		let dashicon_new = ( $(this).attr( 'aria-expanded' ) == 'false' ) ? 'dashicons-minus' : 'dashicons-plus';
		$(this).attr( 'aria-expanded', change );
		$(this).find( 'span.dashicons' ).removeClass( dashicon_old ).addClass( dashicon_new );
		$( '.mcs_location_fields' ).toggle();
		if ( $( '.mcs_location_fields' ).is( ':visible' ) ) {
			$( '.mcs_location_fields' ).addClass( 'active' );
			$( '.mcs_location_fields #event_label' ).trigger( 'focus' );
			$( '.mcs_location_fields [data-required="true"]').attr( 'required', 'true' );
		} else {
			$( '.mcs_location_fields' ).removeClass( 'active' );
			$( '.mcs_location_fields [data-required="true"]').removeAttr( 'required' );
		}
	});

	let image_alt   = document.querySelector( '.mc_event_image_alt' );
	let image_field = document.getElementById( 'mc_event_image' );
	let image_field_clear = document.getElementById( 'mc_event_image_clear' );
	let image_submit = document.querySelector( '.mcs-file-upload-submit' );
	let has_content = false;
	if ( null !== image_field ) {
		if ( ( image_field.getAttribute( 'type' ) == 'url' && image_field.value == '' ) || ( image_field.getAttribute( 'type' ) == 'file' && image_field.files.length == 0 ) ) {
			image_alt.style.display = 'none';
			image_alt.querySelector( 'input' ).removeAttribute( 'required' );
		}
		image_field.addEventListener( 'change', function( el ) {
			has_content = ( ( this.getAttribute( 'type' ) == 'url' && this.value !== '' ) || ( this.getAttribute( 'type' ) == 'file' && this.files.length !== 0 ) ) ? true : false;
			if ( has_content ) {
				image_alt.style.display = 'block';
				image_alt.querySelector( 'input' ).setAttribute( 'required', true );
			} else {
				image_alt.style.display = 'none';
				image_alt.querySelector( 'input' ).removeAttribute( 'required' );
			}
		});
		image_alt.addEventListener( 'keyup', function( el ) {
			if ( 'file' == image_field.getAttribute( 'type' ) && has_content && image_alt.value !== '' ) {
				image_submit.classList.remove( 'mcs-hidden' );
			}
		});
		image_field_clear.addEventListener( 'click', function() {
			image_field.value = '';
			image_alt.style.display = 'none';
			if ( ! image_submit.classList.contains( 'mcs-hidden' ) ) {
				image_submit.classList.add( 'mcs-hidden' );
			}
		});
	}

	$( '.mc-submissions input, .mc-submissions textarea' ).on( 'blur', function(e) {
		let curValue  = $( this ).val();
		let invalid   = $( this ).hasClass( 'invalid' );
		let messageId = $( this ).attr( 'id' );
		let type      = $( this ).attr( 'type' );
		if ( '' !== curValue && invalid ) {
			let valid = true;
			if ( type && 'email' === type ) {
				valid = is_email( curValue );
			}
			if ( type && 'url' === type ) {
				valid = isValidUrl( curValue );
			}
			let name = false;
			let related = false;
			if ( type && 'radio' === type || 'checkbox' === type ) {
				name    = $( this ).attr( 'name' );
				related = document.querySelectorAll( 'input[name="' + name + '"]' );
				valid   = isValidInputGroup( related );
			}
			if ( valid ) {
				if ( 'radio' === type || 'checkbox' === type ) {
					related.forEach((input) => {
						// radio and checkbox inputs always have a value.
						input.classList.remove( 'invalid' );
						let fieldset = input.closest( 'fieldset' );
						let ids = fieldset.getAttribute( 'aria-labelledby' );
						ids = ids.split( ' ' );
						messageId = ids[ ids.length - 1 ];
					});
					$( this ).removeClass( 'invalid' );
					$( '#' + messageId ).hide();
				} else {
					$( this ).removeClass( 'invalid' );
					$( '#' + messageId + '-error' ).hide();
				}
			}
		}
	});

	const forms = document.querySelectorAll( '.mc-submissions form' );
	if ( forms ) {
		let params   = new URL(document.location).searchParams;
		let id       = params.get('mcs_id');
		let isEditing = ( id ) ? true : false
		forms.forEach( (el) => {
			let formId = el.getAttribute( 'id' );
			let responseContainer = document.getElementById( 'mcs-status-' + formId );
			if ( responseContainer ) {
				let submitButton = $( '#mcs-submit-' + formId );
				submitButton.on( 'click', function(e) {
					let validity = checkValidity( formId );
					if ( '' !== validity ) {
						responseContainer.classList.add( 'mcs-invalid', 'visible', 'error' );
						responseContainer.innerHTML = '<h2>' + mcs.heading + '</h2>' + '<ul>' + validity + '</ul>';
						responseContainer.focus();
						responseContainer.scrollIntoView();
					} else {
						responseContainer.classList.remove( 'error', 'mcs-invalid' );
						e.preventDefault();
						// Get form data.
						let formEl      = $( this ).parents( 'form' );
						let formContent = formEl.serialize();
						let eventId     = formEl.find( 'input[name="event_id"]' ).val();
						let data        = {
							'action' : mcs.action,
							'security' : mcs.security,
							'post' : formContent,
							'event_id' : eventId,
						};

						$.post( mcs.ajaxurl, data, function (response) {
							responseContainer.classList.add( 'visible' );
							responseContainer.innerHTML = response.response;
							if ( response.success == 1 ) {
								responseContainer.classList.add( 'mcs-valid' );
								responseContainer.classList.remove( 'mcs-invalid' );
								let paymentKey = formEl.find( 'input[name="mcs_key"]');
								let key = '';
								if ( paymentKey ) {
									key = paymentKey.val();
								}
								if ( ! isEditing ) {
									formEl.trigger( 'reset' );
									// Restore payment key after reset.
									if ( paymentKey ) {
										paymentKey.val( key );
									}
								}
							} else {
								responseContainer.classList.add( 'mcs-invalid' );
								responseContainer.classList.remove( 'mcs-valid' );
							}
							responseContainer.focus();
							responseContainer.scrollIntoView();
						}, "json" );
					}
				});
			}
		});
	}

	function checkValidity( formId ) {
		let formErrors = '';
		let names      = [];
		const requiredFields = document.querySelectorAll( '#mcs_' + formId + ' .mcs-submission *[required]' );
		requiredFields.forEach((el) => {
			let type = el.getAttribute( 'type' );
			if ( 'radio' === type || 'checkbox' === type ) {
				let name = el.getAttribute( 'name' );
				let related = document.querySelectorAll( 'input[name="' + name + '"]' );
				let isChecked = false;
				related.forEach((input) => {
					// radio and checkbox inputs always have a value.
					if ( input.checked ) {
						isChecked = true;
					}
				});
				if ( ! isChecked && ! names.includes( name ) ) {
					formErrors += markInvalid(el,type);
				}
				if ( ! isChecked && names.includes( name ) ) {
					// Still add the invalid class, so that blur events will fire on all members of a group.
					el.classList.add( 'invalid' );
				}
				names.push( name );
			} else if ( ! el.value ) {
				formErrors += markInvalid(el, false);
			}
		});

		return formErrors;
	}

	const fileTypes = [
		"image/apng",
		"image/gif",
		"image/jpeg",
		"image/pjpeg",
		"image/png",
	];

	const isValidUrl = urlString => {
		try {
			return Boolean( new URL( urlString ) );
		}
		catch(e){
			return false;
		}
	}

	function markInvalid( el, type ) {
		let formErrors = '';
		let message    = '';
		el.classList.add( 'invalid' );
		let fieldId = el.getAttribute( 'id' );
		let label   = document.querySelector( 'label[for="' + fieldId + '"]' );
		let existingError = false;
		let legend = false;
		let fieldset = false;
		if ( null !== label ) {
			if ( ! type ) {
				message = label.firstChild.data;
				if ( ! message ) {
					message = label.querySelector( '.label' ).firstChild.data;
				}
			} else {
				fieldset = el.closest( 'fieldset' );
				legend   = fieldset.firstChild;
				message  = legend.textContent;
			}
			if ( 'checkbox' === type ) {
				message = mcs.requiredCheckbox;
			} else if ( 'radio' === type ) {
				message = mcs.requiredRadio;
			} else {
				message = mcs.required + message;
			}
			if ( fieldset ) {
				let aria = fieldset.getAttribute( 'aria-labelledby' );
				fieldset.setAttribute( 'aria-labelledby', aria + ' ' + fieldId + '-error' );
			} else {
				el.setAttribute( 'aria-describedby', fieldId + '-error' );
			}
			let error = document.createElement( 'span' );
			error.classList.add( 'mcs-error-message' );
			error.setAttribute( 'id', fieldId + '-error' );
			error.innerHTML = message;
			if ( fieldId === 'mcs_event_begin' || fieldId === 'mcs_event_end' ) {
				// Place error message outside of datepicker container.
				let parent = el.parentNode.parentNode.parentNode;
				existingError = parent.querySelector( '.mcs-error-message' );
				if ( existingError ) {
					existingError.remove();
				}
				parent.insertAdjacentElement( 'afterend', error );
			} else if ( legend ) {
				// Place error message outside of datepicker container.
				let parent = el.parentNode.parentNode;
				existingError = parent.querySelector( '.mcs-error-message' );
				if ( existingError ) {
					existingError.remove();
				}
				parent.insertAdjacentElement( 'afterend', error );
			} else {
				parent = el.parentNode;
				existingError = parent.querySelector( '.mcs-error-message' );
				if ( existingError ) {
					existingError.remove();
				}
				el.insertAdjacentElement( 'afterend', error );
			}
			formErrors += '<li><a href="#' + fieldId + '">' + message + '</a></li>';
		}

		return formErrors;
	}

	function is_email( email ) {
		let testEmail = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;

		return testEmail.test( email );
	} 

	function isValidInputGroup( related ) {
		let isChecked = false;
		related.forEach((input) => {
			// radio and checkbox inputs always have a value.
			if ( input.checked ) {
				isChecked = true;
			}
		});

		return isChecked;
	} 

	function validFileType(file) {
		return fileTypes.includes(file.type);
	}

	function returnFileSize(number) {
		if (number < 1024) {
			return number + 'bytes';
		} else if (number >= 1024 && number < 1048576) {
			return (number/1024).toFixed(1) + ' KB';
		} else if (number >= 1048576) {
			return (number/1048576).toFixed(1) + ' MB';
		}
	}

	let reader = {};
	let file = {};
	let slice_size = 1000 * 1024; // 1 MB chunk size.

	function start_upload( event ) {
		event.preventDefault();

		reader = new FileReader();
		file   = document.getElementById( 'mc_event_image' ).files[0];

		upload_file( 0, 'mc_event_image' );
	}
	$( '.mcs-file-upload-submit' ).on( 'click', start_upload );

	function upload_file( start, selector ) {
		let next_slice = start + slice_size + 1;
		let blob = file.slice( start, next_slice );
		$( '.mcs-upload-progress' ).html( `Uploading File -  0%` );
		let isComplete = false;
		if ( next_slice > file.size ) {
			isComplete = true;
		}

		reader.onloadend = function( event ) {
			if ( event.target.readyState !== FileReader.DONE ) {
				return;
			}
			let mcs_img = selector;
			let mcs_alt = $( '#event_image_alt' ).val();
			let mcs_id  = $( '#event_post' ).val();
			if ( ! mcs_id ) {
				mcs_id = 0;
			}
			$.ajax( {
				url: mcs.ajaxurl,
				type: 'POST',
				dataType: 'json',
				cache: false,
				data: {
					action: 'mcs_upload_file',
					file_data: event.target.result,
					file: file.name,
					file_type: file.type,
					file_alt: mcs_alt,
					event_post_id: mcs_id,
					img: mcs_img,
					nonce: mcs.security,
					complete: isComplete,
				},
				error: function( jqXHR, textStatus, errorThrown ) {
					console.log( jqXHR, textStatus, errorThrown );
				},
				success: function( data ) {
					let size_done = start + slice_size;
					let percent_done = Math.floor( ( size_done / file.size ) * 100 );
					let imgContainer = document.querySelector( '.mcs-selected-image img' );
					if ( next_slice < file.size ) {
						// Update upload progress
						$( '.mcs-upload-progress' ).html( `Uploading File -  ${percent_done}%` );

						// More to upload, call function recursively
						upload_file( next_slice, selector );
					} else {
						let input = document.querySelector( 'input[name=event_image_id]' );
						if ( typeof data.attachment_id === 'number' ) {
							input.value = data.attachment_id;
							// Update upload progress
							$( '.mcs-upload-progress' ).html( 'Upload Complete!' );
							imgContainer.setAttribute( 'src', data.src );
							imgContainer.setAttribute( 'alt', mcs_alt );
						} else {
							$( '.mcs-upload-progress' ).html( 'Upload Failed' );
						}
					}
				}
			} );
		};

		reader.readAsDataURL( blob );
	}
}(jQuery));