import { ForwardedRef, forwardRef, ReactNode } from 'react';
import {
	FormControl,
	FormControlLabel,
	FormControlLabelProps,
	FormControlProps,
	FormHelperText,
	FormHelperTextProps,
	Switch as MuiSwitch,
	SwitchProps as MuiSwitchProps
} from '@mui/material';

import { useDefaultProps } from '../../hooks';

export type SwitchProps = Omit<MuiSwitchProps, 'value' | 'checked'> & {
	label?: string;
	required?: boolean;
	helperText?: ReactNode;
	value?: boolean;
	error?: boolean;
	disabled?: boolean;
	name?: string;
	slotProps?: {
		formControlLabel?: Omit<FormControlLabelProps, 'control' | 'ref' | 'label' | 'required'>;
		helperText?: FormHelperTextProps;
		formControl?: Omit<FormControlProps, 'name' | 'disabled' | 'error' | 'children' | 'defaultValue'>;
	};
};

const Switch = forwardRef(function Switch(inProps: SwitchProps, ref: ForwardedRef<unknown>) {
	const {
		label,
		required,
		helperText,
		onChange,
		onBlur,
		value,
		name,
		error,
		disabled,

		slotProps: {
			formControl: formControlProps,
			formControlLabel: formControlLabelProps,
			helperText: helperTextProps,
			...switchSlotProps
		} = {},
		...switchProps
	} = useDefaultProps({ name: 'ReevolveSwitch', props: inProps });

	return (
		<FormControl
			{...formControlProps}
			error={error}
			disabled={disabled}
		>
			<FormControlLabel
				{...formControlLabelProps}
				name={name}
				control={
					<MuiSwitch
						{...switchProps}
						slotProps={switchSlotProps}
						value={value}
						checked={value}
						onBlur={onBlur}
						onChange={onChange}
					/>
				}
				ref={ref}
				label={label}
				required={required}
			/>

			{helperText && <FormHelperText {...helperTextProps}>{helperText}</FormHelperText>}
		</FormControl>
	);
});

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

export default Switch;
