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

const TEXT_DOMAIN = 'stock-sync-with-google-sheet-for-woocommerce';

const DISABLED_REASONS = {
	unsupported_type: __( '(This field type is not supported yet)', TEXT_DOMAIN ),
	reserved_word: __( '(Custom field with reserved words are not supported yet)', TEXT_DOMAIN ),
};

/**
 * Searchable multi-select for product custom fields (replaces the legacy select2 box).
 * Keyboard: type to filter, ↑/↓ to move, Enter to add, Backspace on an empty search removes the last tag.
 *
 * @param {Object}   props
 * @param {Array}    props.fields   [{ key, disabled: ''|'unsupported_type'|'reserved_word' }].
 * @param {Array}    props.selected Selected keys.
 * @param {Function} props.onChange Receives the new list of keys.
 */
const CustomFieldSelect = ( { fields, selected, onChange } ) => {
	const listId = useId();
	const inputRef = useRef( null );
	const [ query, setQuery ] = useState( '' );
	const [ open, setOpen ] = useState( false );
	const [ activeIndex, setActiveIndex ] = useState( 0 );

	const matches = useMemo( () => {
		const search = query.trim().toLowerCase();
		return fields.filter( ( field ) => ! selected.includes( field.key ) && ( ! search || field.key.toLowerCase().includes( search ) ) );
	}, [ fields, selected, query ] );

	const add = ( field ) => {
		if ( ! field || field.disabled ) {
			return;
		}
		onChange( [ ...selected, field.key ] );
		setQuery( '' );
		setActiveIndex( 0 );
		inputRef.current?.focus();
	};

	const remove = ( key ) => onChange( selected.filter( ( item ) => item !== key ) );

	const onKeyDown = ( event ) => {
		if ( event.key === 'ArrowDown' ) {
			event.preventDefault();
			setOpen( true );
			setActiveIndex( ( index ) => Math.min( index + 1, matches.length - 1 ) );
		} else if ( event.key === 'ArrowUp' ) {
			event.preventDefault();
			setActiveIndex( ( index ) => Math.max( index - 1, 0 ) );
		} else if ( event.key === 'Enter' ) {
			event.preventDefault();
			add( matches[ activeIndex ] );
		} else if ( event.key === 'Escape' ) {
			setOpen( false );
		} else if ( event.key === 'Backspace' && query === '' && selected.length ) {
			remove( selected[ selected.length - 1 ] );
		}
	};

	return (
		<div className="ssgsw-field-select">
			<div className="ssgsw-field-select__control" onMouseDown={ ( event ) => event.target === event.currentTarget && inputRef.current?.focus() }>
				{ selected.map( ( key ) => (
					<span key={ key } className="ssgsw-field-select__tag">
						{ key }
						<button type="button" onClick={ () => remove( key ) } aria-label={ `${ __( 'Remove', TEXT_DOMAIN ) } ${ key }` }>
							&times;
						</button>
					</span>
				) ) }
				<input
					ref={ inputRef }
					type="text"
					role="combobox"
					aria-expanded={ open }
					aria-controls={ listId }
					aria-autocomplete="list"
					aria-activedescendant={ open && matches[ activeIndex ] ? `${ listId }-${ activeIndex }` : undefined }
					aria-label={ __( 'Custom fields', TEXT_DOMAIN ) }
					placeholder={ selected.length ? '' : __( "Enter your product's custom filed (metadata)", TEXT_DOMAIN ) }
					value={ query }
					onChange={ ( event ) => {
						setQuery( event.target.value );
						setOpen( true );
						setActiveIndex( 0 );
					} }
					onFocus={ () => setOpen( true ) }
					onBlur={ () => setTimeout( () => setOpen( false ), 150 ) }
					onKeyDown={ onKeyDown }
				/>
			</div>

			{ open && (
				<ul className="ssgsw-field-select__list" role="listbox" id={ listId } aria-label={ __( 'Custom fields', TEXT_DOMAIN ) }>
					{ matches.length === 0 && <li className="ssgsw-field-select__empty">{ __( 'No matching custom fields', TEXT_DOMAIN ) }</li> }
					{ matches.map( ( field, index ) => (
						<li
							key={ field.key }
							id={ `${ listId }-${ index }` }
							role="option"
							aria-selected={ index === activeIndex }
							aria-disabled={ !! field.disabled || undefined }
							className={ `ssgsw-field-select__option${ index === activeIndex ? ' is-active' : '' }${ field.disabled ? ' is-disabled' : '' }` }
							onMouseDown={ ( event ) => event.preventDefault() }
							onMouseEnter={ () => setActiveIndex( index ) }
							onClick={ () => add( field ) }
						>
							{ field.key }
							{ field.disabled && <span className="ssgsw_disabled-option"> { DISABLED_REASONS[ field.disabled ] }</span> }
						</li>
					) ) }
				</ul>
			) }
		</div>
	);
};

export default CustomFieldSelect;
