import { ChangeEvent, 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 { Switch, SwitchProps } from '../switch';

export type RHFSwitchProps<T extends FieldValues = FieldValues> = UseControllerProps<T> &
	Omit<SwitchProps, 'value' | 'disabled' | 'ref' | 'error' | 'defaultValue' | 'name'>;

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

		label,
		required,
		helperText,
		onChange,
		onBlur,

		...props
	} = useDefaultProps({ name: 'ReevolveRHFSwitch', props: inProps });

	const { translate } = useLocalization();

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

	function onChangeHandler(e: ChangeEvent<HTMLInputElement>, isChecked: boolean) {
		field.onChange(isChecked);
		onChange?.(e, isChecked);
	}

	function onBlurHandler(e: FocusEvent<HTMLButtonElement, Element>) {
		field.onBlur();
		onBlur?.(e);
	}

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

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

export default RHFSwitch;
