( function ( $ ) {
	$.fn.niceNumber = function ( options ) {
		const settings = $.extend(
			{
				autoSize: true,
				autoSizeBuffer: 1,
				buttonDecrement: '-',
				buttonIncrement: '+',
				buttonPosition: 'around',
			},
			options
		);

		return this.each( function () {
			let currentInput = this,
				$currentInput = $( currentInput ),
				attrMax = null,
				attrMin = null;

			// Handle max and min values
			if (
				typeof $currentInput.attr( 'max' ) !== typeof undefined &&
				$currentInput.attr( 'max' ) !== false
			) {
				attrMax = parseFloat( $currentInput.attr( 'max' ) );
			}

			if (
				typeof $currentInput.attr( 'min' ) !== typeof undefined &&
				$currentInput.attr( 'min' ) !== false
			) {
				attrMin = parseFloat( $currentInput.attr( 'min' ) );
			}

			// if (isNaN(attrMax)) {
			//   attrMax = 44;
			//   console.log(attrMax);
			// }

			// if (isNaN(attrMin)) {
			//   attrMin = 0;
			//   console.log(attrMin);
			// }

			// Fix issue with initial value being < min
			//console.log(currentInput.value);
			if ( attrMin && ! currentInput.value ) {
				$currentInput.val( attrMin );
			}

			// Generate container
			const $inputContainer = $( '<div/>', {
				class: 'ppom-number-plusminus',
			} ).insertAfter( currentInput );

			// Generate interval (object so it is passed by reference)
			const interval = {};

			// Generate buttons
			const $minusButton = $( '<button/>' )
				.attr( 'type', 'button' )
				.html( settings.buttonDecrement )
				.on( 'mousedown mouseup mouseleave', function ( event ) {
					changeInterval( event.type, interval, function () {
						if (
							attrMin == null ||
							isNaN( attrMin ) ||
							attrMin < parseFloat( currentInput.value )
						) {
							currentInput.value--;
						}
					} );

					// Trigger the input event here to avoid event spam
					if (
						event.type == 'mouseup' ||
						event.type == 'mouseleave'
					) {
						$currentInput.trigger( 'change' );
					}
				} );

			const $plusButton = $( '<button/>' )
				.attr( 'type', 'button' )
				.html( settings.buttonIncrement )
				.on( 'mousedown mouseup mouseleave', function ( event ) {
					changeInterval( event.type, interval, function () {
						if (
							attrMax == null ||
							isNaN( attrMax ) ||
							attrMax > parseFloat( currentInput.value )
						) {
							currentInput.value++;
						}
					} );

					// Trigger the input event here to avoid event spam
					if (
						event.type == 'mouseup' ||
						event.type == 'mouseleave'
					) {
						$currentInput.trigger( 'change' );
					}
				} );

			// Append elements
			switch ( settings.buttonPosition ) {
				case 'left':
					$minusButton.appendTo( $inputContainer );
					$plusButton.appendTo( $inputContainer );
					$currentInput.appendTo( $inputContainer );
					break;
				case 'right':
					$currentInput.appendTo( $inputContainer );
					$minusButton.appendTo( $inputContainer );
					$plusButton.appendTo( $inputContainer );
					break;
				case 'around':
				default:
					$minusButton.appendTo( $inputContainer );
					$currentInput.appendTo( $inputContainer );
					$plusButton.appendTo( $inputContainer );
					break;
			}

			// Nicely size input
			if ( settings.autoSize ) {
				$currentInput.width(
					$currentInput.val().length + settings.autoSizeBuffer + 'ch'
				);
				$currentInput.on( 'keyup input', function () {
					$currentInput.animate(
						{
							width:
								$currentInput.val().length +
								settings.autoSizeBuffer +
								'ch',
						},
						200
					);
				} );
			}
		} );
	};

	function changeInterval( eventType, interval, callback ) {
		if ( eventType == 'mousedown' ) {
			interval.timeout = setTimeout( function () {
				interval.actualInterval = setInterval( function () {
					callback();
				}, 100 );
			}, 200 );
			callback();
		} else {
			if ( interval.timeout ) {
				clearTimeout( interval.timeout );
			}
			if ( interval.actualInterval ) {
				clearInterval( interval.actualInterval );
			}
		}
	}
} )( jQuery );
