import { useState, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Free-text chip input for rule conditions whose values cannot be picked from a list.
 *
 * Postcodes are the motivating case: there is no enumerable set to search, and a store
 * needs to express wildcards and ranges as well as literal values. Conditions declare
 * `source: 'tags'` in the capabilities payload to get this instead of a select.
 *
 * Deliberately reuses the AsyncMultiSelect chip styles so a rule row looks the same
 * whichever control it happens to use.
 */
export default function TagInput( { values = [], onChange, placeholder, hint } ) {
	const [ draft, setDraft ] = useState( '' );
	const inputRef = useRef();

	const commit = ( raw ) => {
		// Accept comma- and space-separated pastes in one go, so a store can paste a
		// list out of a spreadsheet rather than typing each entry.
		const parts = String( raw )
			.split( /[\s,]+/ )
			.map( ( v ) => v.trim() )
			.filter( Boolean );

		if ( ! parts.length ) return;

		const next = [ ...values ];
		parts.forEach( ( p ) => {
			if ( ! next.includes( p ) ) next.push( p );
		} );

		onChange( next );
		setDraft( '' );
	};

	const onKeyDown = ( e ) => {
		if ( e.key === 'Enter' || e.key === ',' ) {
			e.preventDefault();
			commit( draft );
		} else if ( e.key === 'Backspace' && draft === '' && values.length ) {
			onChange( values.slice( 0, -1 ) );
		}
	};

	const remove = ( v ) => onChange( values.filter( ( x ) => x !== v ) );

	return (
		<div className="edfw-ams edfw-taginput">
			<div className="edfw-ams__control" onClick={ () => inputRef.current?.focus() }>
				{ values.map( ( v ) => (
					<span className="edfw-ams__chip" key={ v }>
						{ v }
						<button
							type="button"
							onClick={ ( e ) => { e.stopPropagation(); remove( v ); } }
							aria-label={ __( 'Remove', 'wpactpro-estimated-delivery-date' ) }
						>✕</button>
					</span>
				) ) }
				<input
					ref={ inputRef }
					className="edfw-taginput__field"
					type="text"
					value={ draft }
					placeholder={ values.length ? '' : ( placeholder || __( 'Any', 'wpactpro-estimated-delivery-date' ) ) }
					onChange={ ( e ) => setDraft( e.target.value ) }
					onKeyDown={ onKeyDown }
					// Commit whatever is typed when focus leaves, so a value is never
					// silently lost by clicking Save without pressing Enter first.
					onBlur={ () => commit( draft ) }
				/>
			</div>
			{ hint && <div className="edfw-taginput__hint">{ hint }</div> }
		</div>
	);
}
