/**
 * WordPress dependencies
 */
import { TextControl } from '@safe-wordpress/components';

/**
 * External dependencies
 */
import type { Maybe } from '@nelio-content/types';

export type NumberControlProps = {
	readonly id?: string;
	readonly label?: string;
	readonly className?: string;
	readonly value?: number | string;
	readonly onChange: ( val?: number ) => void;
	readonly min?: number;
	readonly max?: number;
	readonly disabled?: boolean;
	readonly placeholder?: string;
};

export const NumberControl = ( {
	id,
	className,
	label,
	value,
	onChange,
	min = -Infinity,
	max = Infinity,
	disabled,
	placeholder,
}: NumberControlProps ): JSX.Element => {
	if ( ! label ) {
		return (
			<input
				id={ id }
				className={ className }
				type="number"
				disabled={ disabled }
				min={ min }
				max={ max }
				value={ numberize( value ) }
				placeholder={ placeholder }
				onChange={ ( ev ) => {
					const newValue = Number.parseInt( ev.target.value );
					return undefined === newValue ||
						Number.isNaN( newValue ) ||
						newValue < min ||
						max < newValue
						? onChange( undefined )
						: onChange( newValue );
				} }
			/>
		);
	}

	return (
		<TextControl
			id={ id }
			className={ className }
			type="number"
			disabled={ disabled }
			min={ min }
			max={ max }
			label={ label }
			value={ undefined === value ? '' : `${ value }` }
			placeholder={ placeholder }
			onChange={ ( input ) => {
				const newValue = Number.parseInt( input );
				return undefined === newValue ||
					Number.isNaN( newValue ) ||
					newValue < min ||
					max < newValue
					? onChange( undefined )
					: onChange( newValue );
			} }
		/>
	);
};

// =======
// HELPERS
// =======

function numberize( value: NumberControlProps[ 'value' ] ): Maybe< number > {
	if ( 'number' === typeof value ) {
		return value;
	}

	if ( 'string' !== typeof value ) {
		return undefined;
	}

	const num = Number.parseInt( value );
	return isNaN( num ) ? undefined : num;
}
