const entityEditing = ( entityForm ) => {

	const entityType = entityForm.querySelector('#pwp_form_type');
	const typeForms = entityForm.querySelectorAll('[data-condition-type]');
	if ( ! entityType || 0 === typeForms.length ) {
		return;
	}
	const conditionAddition = entityForm.querySelector('#condition-addition');
	const conditionOperator = entityForm.querySelector('#condition-operator');

	/**
	 * Toggle hidden attribute across all form sub-sections, keeping the one matching `type` visible
	 *
	 * @param {String} type Type sub-section to be visible
	 */
	const displayTypeForm = function ( type ) {
		typeForms.forEach( form => {
			const matches_type = form.getAttribute('data-condition-type') === type;
			form.hidden = ! matches_type;
			// Check for type having condition template for additional conditions.
			if ( matches_type ) {
				const noMultiple = ( null === form.querySelector( ':scope > template' ) );
				// Hide the additional row button if the condition doesn't support multiple inputs.
				conditionAddition.hidden = ( noMultiple );
				if ( conditionOperator ) {
					const noAutoComplete = ( null === form.querySelector( ':scope auto-complete' ) );
					// Hide the multiple operator selector if the condition doesn't support multiple conditions.
					conditionOperator.hidden = ( noAutoComplete && noMultiple );
				}
				// Revert any hiding of inputs.
				toggleRequired( form, true );
			}
			if ( ! matches_type ) {
				// Hide unnessary required fields as they will gum up the submission.
				toggleRequired( form );
			}
		});
	}

	/**
	 * Toggle required attributes within a form.
	 *
	 * @param {Node}    form           Form node element
	 * @param {Boolean} resetRequired  True to revert the change
	 */
	const toggleRequired = function( form, resetRequired = false ) {
		if ( ! resetRequired ) {
			const inputs = form.querySelectorAll( '[required]' );
			inputs.forEach( requiredInput => {
				requiredInput.setAttribute( 'data-required', 'required' );
				requiredInput.required = false;
			} );
		} else {
			const inputs = form.querySelectorAll( '[data-required]' );
			inputs.forEach( requiredInput => {
				requiredInput.removeAttribute( 'data-required' );
				requiredInput.required = true;
			} );
		}
	}

	// Track any change to the overall type select element.
	entityType.addEventListener( 'change', function() {
		displayTypeForm( entityType.options[entityType.selectedIndex].value );
	} );

	// On load set the initial type form section based on what has been pre-set (if editing)
	var currentType = entityType.selectedIndex ? entityType.options[entityType.selectedIndex].value : '';
	displayTypeForm( currentType );

	/**
	 * Ties taxonomy <select> to their term <auto-complete> to ensure the correct taxonomy is set.
	 */
	const updateLinkedTaxonomyTermAutoCompleteFields = (form) => {
		const taxFormSelects = form.querySelectorAll('[data-type="taxonomy"]');
		if ( taxFormSelects.length ) {
			taxFormSelects.forEach( selectField => {
				selectField.addEventListener( 'change', function() {
					const taxonomy = selectField.selectedIndex ? selectField.options[selectField.selectedIndex].value : '';
					const consContainer = selectField.closest('[data-condition="row"]');
					if ( consContainer ) {
						const autocompleteField = consContainer.querySelector('auto-complete');
						if ( autocompleteField ) {
							autocompleteField.setAttribute( 'taxonomy', taxonomy );
						}
					}
				} );
			} );
		}
	}
	updateLinkedTaxonomyTermAutoCompleteFields(entityForm);

	const usedRandIds = [];
	/**
	 * Return random number up to 1000. Ensure not already generated.
	 */
	const randId = () => {
		let num;
		do {
			num = Math.floor(Math.random() * 1000);
		} while (usedRandIds.includes(num));

		usedRandIds.push(num);
		return num;
	}

	/**
	 * Replaces {{ID}} placeholders in templates with random unique IDs.
	 *
	 * @param {String} template The template string
	 */
	const updateIDs = (template) => {
		'use strict';

		const elements = template.querySelectorAll( '[id*="_{{ID}}"' );
		if ( ! elements ) {
			return template;
		}

		elements.forEach( (ele) => {
			let origID = ele.id;
			let newID = ele.id.replace( '{{ID}}', randId() );

			// Check for potential corresponding <label> that must also use the ID.
			let maybeLabel = template.querySelector( `[for="${origID}"]` );
			if ( maybeLabel ) {
				maybeLabel.setAttribute( 'for', newID );
			}
			ele.id = newID;
		});
		return template;
	}

	/**
	 * Allow delegation of clicks to the form itself from all buttons. Supports adding/removing
	 * buttons, such as the removals within condition containers, without adding eventListeners.
	 */
	entityForm.addEventListener( 'click', function(e) {
		let button = e.target.closest('button');
		if ( ! button )
			return;

		var consRow, consContainer, templateRow, updateCount = false;
		switch(button.value) {
			case 'add' :
				consContainer = entityForm.querySelector('[data-condition-type]:not([hidden])');
				templateRow = consContainer.querySelector(':scope > template').content.cloneNode(true);
				consContainer.appendChild( updateIDs( templateRow ) );
				// Re-setup any taxonomy term fields.
				updateLinkedTaxonomyTermAutoCompleteFields(entityForm);
				updateCount = true;
			break;

			case 'remove':
				consRow = button.closest('[data-condition="row"]');
				consContainer = consRow.closest('[data-condition-type]');
				consContainer.removeChild(consRow);
				updateCount = true;
				break;
		}
		if(updateCount){
			// Update the count of overall conditions, using the data-contition="row"
			var count = consContainer.querySelectorAll('[data-condition="row"]').length;
			consContainer.setAttribute( 'data-condition-count', count );
		}
	} );

};

export default entityEditing;
