import { FocusEvent } from 'react';
import { FieldValues, useController, UseControllerProps } from 'react-hook-form';
import { isBoolean, isString } from 'lodash';

import { useDefaultProps } from '../../hooks';
import { useLocalization } from '../../localization';
import NumberField, { NumberFieldProps } from '../number-field/NumberField';

export type RHFNumberFieldProps<T extends FieldValues = FieldValues> = Omit<
	NumberFieldProps,
	'value' | 'name' | 'disabled' | 'error' | 'onChange'
> &
	UseControllerProps<T> & {
		onChange?: (value: number | string | null) => void;
	};

function RHFNumberField<T extends FieldValues>(inProps: RHFNumberFieldProps<T>) {
	const {
		/** React Hook Form */
		name,
		rules,
		control,
		disabled,
		defaultValue,
		shouldUnregister,
		/** React Hook Form */

		required,
		helperText,
		label,
		inputRef,
		onChange,
		onBlur,
		...props
	} = useDefaultProps({ name: 'ReevolveRHFNumberField', props: inProps });

	const { translate } = useLocalization();

	const {
		field,
		fieldState: { error }
	} = useController<T>({
		name,
		control,
		defaultValue,
		shouldUnregister,
		disabled,
		rules: rules && {
			...rules,
			required: rules?.required === true ? translate('validation.required', { label }) : rules?.required,
			min:
				typeof rules?.min === 'number'
					? {
							value: rules.min,
							message: translate('validation.min', { min: rules.min, label })
						}
					: rules?.min,
			max:
				typeof rules?.max === 'number'
					? {
							value: rules.max,
							message: translate('validation.max', { max: rules.max, label })
						}
					: rules?.max
		}
	});

	const onChangeHandler = (value: number | string | null) => {
		field.onChange(value);
		onChange?.(value);
	};

	function onBlurHandler(e: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) {
		field.onBlur();
		onBlur?.(e);
	}

	return (
		<NumberField
			fullWidth
			{...props}
			label={label}
			inputRef={inputRef || field.ref}
			name={field.name}
			disabled={field.disabled}
			value={field.value}
			onChange={onChangeHandler}
			onBlur={onBlurHandler}
			required={
				isBoolean(rules?.required) ? rules.required : isString(rules?.required) || rules?.required?.value || required
			}
			error={!!error}
			helperText={error?.message || helperText}
		/>
	);
}

declare module '@mui/material' {
	interface Components {
		ReevolveRHFNumberField?: {
			defaultProps?: Partial<RHFNumberFieldProps>;
		};
	}
}

export default RHFNumberField;
