/**
 * WordPress dependencies
 */
import { BaseControl } from '@safe-wordpress/components';
import { useInstanceId } from '@safe-wordpress/compose';
import * as icons from '@safe-wordpress/icons';

const {
	Icon: _,
	// Deprecated aliases
	warning: __,
	...availableIcons
} = icons;

/**
 * External dependencies
 */
import clsx from 'clsx';
import { OptionProps, SingleValueProps } from 'react-select';
import { find } from 'lodash';

/**
 * Internal dependencies
 */
import { StylizedSelectControl } from '../stylized-select-control';
import './style.scss';

type IconSelectorProps = {
	readonly className?: string;
	readonly label?: string;
	readonly help?: string;
	readonly icon?: string;
	readonly onChange: ( icon?: string ) => void;
};

export const IconSelector = ( {
	className,
	label,
	help,
	icon,
	onChange,
}: IconSelectorProps ): JSX.Element | null => {
	const instanceId = useInstanceId( IconSelector );

	const iconValue = !! icon
		? find( ICON_OPTIONS, { value: icon } )
		: undefined;

	return (
		<BaseControl
			className={ className }
			label={ label }
			help={ help }
			id={ `nelio-content-icon-selector-${ instanceId }` }
		>
			<StylizedSelectControl< IconData, false >
				options={ ICON_OPTIONS }
				value={ iconValue }
				onChange={ ( option ) => onChange( option?.value ) }
				styles={ {
					menuList: ( provided ) => ( {
						...provided,
						maxHeight: 150,
					} ),
				} }
				components={ {
					Option: IconOption,
					SingleValue: IconSingleValue,
				} }
			/>
		</BaseControl>
	);
};

type IconData = {
	icon: JSX.Element;
	value: string;
	label: string;
};
const ICON_OPTIONS: ReadonlyArray< IconData > = Object.entries(
	availableIcons
).map( ( [ name, icon ] ) => ( {
	icon,
	value: name,
	label: name,
} ) );

const IconOption = ( {
	data: { label, icon },
	isFocused,
	isSelected,
	innerRef,
	innerProps,
}: OptionProps< IconData > ): JSX.Element => (
	<div
		ref={ innerRef }
		className={ clsx( {
			'nelio-content-icon-option-in-icon-selector': true,
			'nelio-content-icon-option-in-icon-selector--is-focused': isFocused,
			'nelio-content-icon-option-in-icon-selector--is-selected':
				isSelected,
		} ) }
		{ ...innerProps }
	>
		<div className="nelio-content-icon-option-in-icon-selector__icon-wrapper">
			<div className="nelio-content-icon-option-in-icon-selector__icon">
				{ icon }
			</div>
		</div>

		<div className="nelio-content-icon-option-in-icon-selector__label">
			{ label }
		</div>
	</div>
);

const IconSingleValue = ( {
	data: { label, icon },
	innerProps,
}: SingleValueProps< IconData > ): JSX.Element => (
	<div
		className="nelio-content-single-value-in-icon-selector"
		{ ...innerProps }
	>
		<div className="nelio-content-single-value-in-icon-selector__icon-wrapper">
			<div className="nelio-content-single-value-in-icon-selector__icon">
				{ icon }
			</div>
		</div>

		<div className="nelio-content-single-value-in-icon-selector__label">
			{ label }
		</div>
	</div>
);
