/**
 * Topping Items admin JavaScript.
 *
 * @package FoodOrd
 */

/**
 * Topping Items admin JavaScript.
 *
 * @package Foodord
 */

( function( $ ) {
	'use strict';

	const toppingCounters = {};

	// eslint-disable-next-line no-unused-vars
	function ensureLocalizedObject() {
		if ( 'undefined' === typeof window.foodordTopping ) {
			window.foodordTopping = {
				labelText: 'Label',
				priceText: 'Price',
			};
		}
	}


	function getSortable( groupType ) {
		return $( '.topping-items-sortable[data-group-type="' + groupType + '"]' );
	}

	function getPanel( groupType ) {
		return $( '.topping-items-panel[data-group-type="' + groupType + '"]' );
	}

	function ensureCounter( groupType ) {
		if ( 'undefined' === typeof toppingCounters[ groupType ] ) {
			const $container = getSortable( groupType );
			const existingRows = $container.find( '.topping-item-row' ).length;
			// Set counter to the highest existing index + 1
			let maxIndex = 0;
			$container.find( '.topping-item-row' ).each( function() {
				const index = parseInt( $( this ).data( 'topping-index' ), 10 );
				if ( ! isNaN( index ) && index >= maxIndex ) {
					maxIndex = index + 1;
				}
			} );
			toppingCounters[ groupType ] = Math.max( existingRows, maxIndex );
		}

		return toppingCounters[ groupType ];
	}

	function isPriceHidden( groupType ) {
		const $toggle = $( '.toggle-hide-price[data-group-type="' + groupType + '"]' );
		return $toggle.length > 0 && $toggle.is( ':checked' );
	}

	function setHidePriceState( groupType, shouldHide ) {
		const $panel = getPanel( groupType );
		if ( $panel.length === 0 ) {
			return;
		}

		$panel.attr( 'data-hide-price', shouldHide ? '1' : '0' );

		const $hiddenState = $( '#topping_hide_price_state_' + groupType );
		if ( $hiddenState.length ) {
			$hiddenState.val( shouldHide ? '1' : '0' );
		}
	}

	function buildToppingRow( groupType, index ) {
		const labelId = 'topping_item_label_' + groupType + '_' + index;
		const priceId = 'topping_item_price_' + groupType + '_' + index;
		const labelText = window.foodordTopping.labelText;
		const priceText = '0';
		const defaultText = window.foodordTopping.defaultText || 'Mark topping as default';
		const supportsDefault = ['dropdown', 'radio', 'checkbox'].includes( groupType );
		const currencyCode = window.foodordTopping.currencyCode || '';

		const priceInput = currencyCode
			? '<div class="wrc-currency-input" data-currency="' + currencyCode + '">' +
				'<input type="number" id="' + priceId + '" name="topping_item_price[]" class="regular-text wrc-number-input" step="0.01" min="0" placeholder="' + priceText + '" />' +
			'</div>'
			: '<input type="number" id="' + priceId + '" name="topping_item_price[]" class="regular-text wrc-number-input" step="0.01" min="0" placeholder="' + priceText + '" />';

		const defaultControl = supportsDefault
			? '<div class="topping-default-control">'
				+ '<label class="topping-default-label" for="topping_item_default_' + groupType + '_' + index + '">'
					+ '<input type="checkbox" id="topping_item_default_' + groupType + '_' + index + '" class="topping-default-checkbox" name="topping_item_default[' + groupType + '][]" value="' + index + '" aria-label="' + defaultText + '" />'
					+ '<span class="screen-reader-text">' + defaultText + '</span>'
				+ '</label>'
			+ '</div>'
			: '';

		return (
			'<div class="topping-item-row" data-group-type="' + groupType + '" data-topping-index="' + index + '">' +
				'<div class="topping-item-fields">' +
					'<div class="wrc-field wrc-field--label">' +
						'<label class="wrc-label" for="' + labelId + '">' + labelText + '</label>' +
						'<input type="text" id="' + labelId + '" name="topping_item_label[]" class="regular-text" placeholder="' + labelText + '" />' +
					'</div>' +
					'<div class="wrc-field wrc-field--price">' +
						'<label class="wrc-label" for="' + priceId + '">' + window.foodordTopping.priceText + '</label>' +
						 priceInput +
					'</div>' +
				'</div>' +
				'<div class="topping-item-actions">' +
					'<div class="drag-handle" title="Drag to reorder" aria-label="Drag to reorder">' +
						'<span class="drag-dots" aria-hidden="true"></span>' +
					'</div>' +
					'<button type="button" class="remove-topping-item" data-group-type="' + groupType + '" title="Remove topping item" aria-label="Remove topping item">' +
						'<span class="dashicons dashicons-no-alt" aria-hidden="true"></span>' +
					'</button>' +
					 defaultControl +
				'</div>' +
			'</div>'
		);
	}

	function updateRemoveButtonStates( groupType ) {
		const $container = getSortable( groupType );
		const totalItems = $container.find( '.topping-item-row' ).length;
		const $removeButtons = $container.find( '.remove-topping-item' );

		if ( totalItems <= 1 ) {
			$removeButtons.prop( 'disabled', true ).addClass( 'disabled' );
		} else {
			$removeButtons.prop( 'disabled', false ).removeClass( 'disabled' );
		}
	}

	function getStepPrecision( step ) {
		const stepString = step.toString();
		if ( stepString.indexOf( '.' ) === -1 ) {
			return 0;
		}

		return stepString.split( '.' )[1].length;
	}

	function adjustNumberInputValue( $input, direction ) {
		if ( $input.length === 0 || $input.prop( 'disabled' ) ) {
			return;
		}

		const stepAttr = parseFloat( $input.attr( 'step' ) );
		const minAttr = parseFloat( $input.attr( 'min' ) );
		const maxAttr = parseFloat( $input.attr( 'max' ) );
		const step = ! Number.isNaN( stepAttr ) && stepAttr > 0 ? stepAttr : 1;
		const precision = getStepPrecision( step );
		const currentValueAttr = parseFloat( $input.val() );
		const hasCurrentValue = ! Number.isNaN( currentValueAttr );
		let workingValue = hasCurrentValue ? currentValueAttr : ( ! Number.isNaN( minAttr ) ? minAttr : 0 );

		if ( ! hasCurrentValue && direction === 'decrease' ) {
			// If the field is empty and the user wants to decrease, clamp to min without subtracting.
			workingValue = ! Number.isNaN( minAttr ) ? minAttr : 0;
		} else if ( direction === 'increase' ) {
			workingValue += step;
		} else if ( direction === 'decrease' ) {
			workingValue -= step;
		}

		if ( ! Number.isNaN( minAttr ) && workingValue < minAttr ) {
			workingValue = minAttr;
		}

		if ( ! Number.isNaN( maxAttr ) && workingValue > maxAttr ) {
			workingValue = maxAttr;
		}

		const formattedValue = workingValue.toFixed( precision );

		$input.val( formattedValue );
		$input.trigger( 'input' );
		$input.trigger( 'change' );
	}

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

		const $button = $( event.currentTarget );
		if ( $button.prop( 'disabled' ) ) {
			return;
		}

		const direction = $button.data( 'direction' );
		const inputId = $button.data( 'input-id' );
		if ( ! direction || ! inputId ) {
			return;
		}

		const $input = $( '#' + inputId );
		adjustNumberInputValue( $input, direction );
	}

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

		const $button = $( event.currentTarget );
		if ( $button.prop( 'disabled' ) ) {
			return false;
		}

		const groupType = $button.data( 'group-type' );
		const $container = getSortable( groupType );

		if ( $container.length === 0 ) {
			console.error( 'Sortable container not found for group type:', groupType );
			return false;
		}

		const currentIndex = ensureCounter( groupType );
		const newRow = buildToppingRow( groupType, currentIndex );

		$container.append( newRow );

		if ( $container.hasClass( 'ui-sortable' ) ) {
			$container.sortable( 'refresh' );
		}

		toppingCounters[ groupType ] = currentIndex + 1;

		const focusSelector = '#topping_item_label_' + groupType + '_' + currentIndex;
		$( focusSelector ).focus();

		updateRemoveButtonStates( groupType );
		setHidePriceState( groupType, isPriceHidden( groupType ) );
	}

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

		const $button = $( event.currentTarget );
		if ( $button.prop( 'disabled' ) ) {
			return false;
		}

		const groupType = $button.data( 'group-type' ) || $button.closest( '.topping-items-sortable' ).data( 'group-type' );
		const $container = getSortable( groupType );
		const $row = $button.closest( '.topping-item-row' );

		$row.fadeOut( 300, function() {
			$( this ).remove();

			if ( $container.hasClass( 'ui-sortable' ) ) {
				$container.sortable( 'refresh' );
			}

			if ( 'function' === typeof window.updateToppingIndices ) {
				window.updateToppingIndices();
			}

			updateRemoveButtonStates( groupType );
		} );
	}

	$( document ).ready( function() {

		$( document ).on( 'click', '.add-new-topping', handleAddNewTopping );
		$( document ).on( 'click', '.remove-topping-item', handleRemoveTopping );
		$( document ).on( 'click', '.topping-checkbox-limit-control', handleCheckboxLimitControl );
		$( document ).on( 'change', '.topping-default-checkbox', function( event ) {
			const $checkbox = $( event.currentTarget );
			if ( ! $checkbox.prop( 'checked' ) ) {
				return;
			}

			const $row = $checkbox.closest( '.topping-item-row' );
			const groupType = $row.data( 'group-type' );
			if ( ! groupType ) {
				return;
			}

			const $container = getSortable( groupType );
			$container.find( '.topping-default-checkbox' ).not( $checkbox ).prop( 'checked', false );
		} );

		$( document ).on( 'foodord:toppingsGroupTypeActivated', function( event, groupType ) {
			setHidePriceState( groupType, isPriceHidden( groupType ) );
			updateRemoveButtonStates( groupType );
			const $panel = getPanel( groupType );
			if ( $panel.length ) {
				const isDisabled = $panel.find( '.wrc-number-input' ).first().prop( 'disabled' );
				$panel.find( '.topping-checkbox-limit-control' ).prop( 'disabled', isDisabled );
			}
		} );

		$( '.topping-items-sortable' ).each( function() {
			const groupType = $( this ).data( 'group-type' );
			ensureCounter( groupType );
			updateRemoveButtonStates( groupType );
		} );

		$( '.toggle-hide-price' ).each( function() {
			const $toggle = $( this );
			setHidePriceState( $toggle.data( 'group-type' ), $toggle.is( ':checked' ) );
		} );

		$( document ).on( 'change', '.toggle-hide-price', function() {
			const $toggle = $( this );
			setHidePriceState( $toggle.data( 'group-type' ), $toggle.is( ':checked' ) );
		} );
	} );

	// Expose helper for other scripts.
	window.foodordUpdateRemoveButtonStates = updateRemoveButtonStates;

	// Auto hide only success notices after saving (after 5 seconds)
	$(document).ready(function() {
		const $successNotice = $('.notice.notice-success.is-dismissible');
		if ($successNotice.length > 0) {
			setTimeout(function() {
				$successNotice.fadeOut(500, function() {
					$(this).remove();
				});
			}, 5000);
		}
	});

} )( jQuery );
