/**
 * @function useDropdownControl
 * @description Adds the control handlers to props.
 *
 * @since 4.5.0
 *
 * @param {object}   props    The props to add handlers to.
 * @param {Function} useStore The useStore hook.
 *
 * @return {object} The modified props.
 */
const useDropdownControl = ( props = {}, useStore = () => {} ) => {
	const {
		multi = false,
		onClose = () => {},
		onAfterClose = () => {},
		onOpen = () => {},
		onAfterOpen = () => {},
	} = props;

	const listItems = useStore( ( state ) => state.listItems );
	const selectedItem = useStore( ( state ) => state.selectedItem );
	const setActiveItem = useStore( ( state ) => state.setActiveItem );
	const setSelectedItem = useStore( ( state ) => state.setSelectedItem );
	const setSearchValue = useStore( ( state ) => state.setSearchValue );
	const setOpen = useStore( ( state ) => state.setOpen );
	const setHide = useStore( ( state ) => state.setHide );
	const setReveal = useStore( ( state ) => state.setReveal );
	const triggerRef = useStore( ( state ) => state.triggerRef );

	/**
	 * @function close
	 * @description Closes the dropdown.
	 *
	 * @since 4.5.0
	 *
	 * @param {Event} event The event object.
	 */
	const close = ( event ) => {
		onClose?.( event );
		setOpen( false );
		setHide( true );
		setTimeout( () => {
			setHide( false );
			setSearchValue( '' );
			onAfterClose?.( event );
		}, 150 );
	};
	/**
	 * @function open
	 * @description Opens the dropdown.
	 *
	 * @since 4.5.0
	 *
	 * @param {Event} event The event object.
	 */
	const open = ( event ) => {
		onOpen?.( event );
		setReveal( true );
		requestAnimationFrame( () => {
			setOpen( true );
			setTimeout( () => {
				setReveal( false );
				onAfterOpen?.( event );
			}, 150 );
		} );
	};
	/**
	 * @function resetAndClose
	 * @description Resets and closes the dropdown.
	 *
	 * @since 4.5.0
	 *
	 * @param {Event} event The event object.
	 */
	const resetAndClose = ( event ) => {
		setTimeout( () => {
			if ( multi ) {
				setActiveItem( listItems.items[ 0 ] );
			} else {
				setActiveItem( selectedItem );
			}
		}, 150 );
		close( event );
	};
	/**
	 * @function selectItem
	 * @description Selects an item in the list.
	 *
	 * @since 4.5.0
	 *
	 * @param {object} item The item to select.
	 *
	 * @return {Function} The event handler.
	 */
	const selectItem = ( item ) => ( event ) => {
		if ( multi ) {
			const selected = selectedItem.some( ( selItem ) => selItem.value === item.value );
			// Handle multi case.
			if ( selected ) {
				// If already selected, remove it.
				setSelectedItem( selectedItem.filter( ( selItem ) => selItem.value !== item.value ) );
			} else {
				// Otherwise add it to the selected items.
				setSelectedItem( [ ...selectedItem, item ] );
			}
			return;
		}

		// Not multi, set selected item.
		setSelectedItem( item );
		requestAnimationFrame( () => {
			close( event );
			triggerRef?.current?.focus();
		} );
	};
	/**
	 * @function selectMultipleItems
	 * @description Selects multiple items.
	 *
	 * @since 4.5.0
	 *
	 * @param {Array} items The items to select.
	 */
	const selectMultipleItems = ( items = [] ) => {
		const newSelectedItems = items.reduce( ( carry, item ) => {
			// Check if item is already selected.
			if ( selectedItem.some( ( selItem ) => selItem.value === item.value ) ) {
				return carry;
			}

			// Add item to selected items.
			carry.push( item );
			return carry;
		}, [ ...selectedItem ] );

		setSelectedItem( newSelectedItems );
	};

	return {
		...props,
		close,
		open,
		resetAndClose,
		selectItem,
		selectMultipleItems,
	};
};

export default useDropdownControl;
