import React, { useImperativeHandle, useRef } from 'react';
import { HiOutlineEye, HiOutlineEyeOff } from 'react-icons/hi';
import { IconButton, IconButtonProps, InputAdornment } from '@mui/material';
import { isFunction } from 'lodash';

import { useDefaultProps } from '../../hooks';
import { TextField, TextFieldProps } from '../text-field';

export type PasswordProps<Nullable extends boolean = true> = Omit<TextFieldProps<Nullable>, 'select'> & {
	/**
	 * position of show/hide password toggler button in input
	 * @default 'end'
	 */
	showPasswordTogglerButtonPosition?: 'end' | 'start';
	slots?: {
		showPasswordIcon?: React.ElementType;
		hidePasswordIcon?: React.ElementType;
	};
	slotProps?: {
		showPasswordIcon?: React.SVGAttributes<SVGElement>;
		hidePasswordIcon?: React.SVGAttributes<SVGElement>;
		showPasswordTogglerButton?: Omit<IconButtonProps, 'onClick'>;
	};
};

function Password<Nullable extends boolean>(inProps: PasswordProps<Nullable>) {
	const _inputRef = useRef<HTMLInputElement>(null);

	const {
		slotProps: inSlotProps,
		slots: inSlots,
		showPasswordTogglerButtonPosition = 'end',
		autoDirection = false,
		inputRef,
		...props
	} = useDefaultProps({ name: 'RematePassword', props: inProps });

	useImperativeHandle(inputRef, () => _inputRef.current, []);

	const [showPassword, setShowPassword] = React.useState(false);

	const toggleShowPassword = () => {
		setShowPassword((show) => !show);
		_inputRef.current?.focus();
	};

	const {
		showPasswordIcon: showPasswordIconProps,
		hidePasswordIcon: hidePasswordIconProps,
		showPasswordTogglerButton: showPasswordTogglerButtonProps,
		...slotProps
	} = inSlotProps ?? {};

	const { showPasswordIcon, hidePasswordIcon, ...slots } = inSlots ?? {};

	const ShowPasswordIcon = showPasswordIcon ?? HiOutlineEye;
	const HidePasswordIcon = hidePasswordIcon ?? HiOutlineEyeOff;

	const inputAddorment = (
		<InputAdornment position={showPasswordTogglerButtonPosition}>
			<IconButton
				tabIndex={-1}
				{...showPasswordTogglerButtonProps}
				onClick={toggleShowPassword}
				sx={(theme) => ({
					...(showPasswordTogglerButtonPosition === 'end' ? { marginRight: -1.5 } : { marginLeft: -1.5 }),
					...(isFunction(showPasswordTogglerButtonProps?.sx)
						? (showPasswordTogglerButtonProps.sx as Function)(theme)
						: showPasswordTogglerButtonProps?.sx)
				})}
			>
				{showPassword ? (
					<HidePasswordIcon {...hidePasswordIconProps} />
				) : (
					<ShowPasswordIcon {...showPasswordIconProps} />
				)}
			</IconButton>
		</InputAdornment>
	);

	return (
		<TextField
			inputRef={_inputRef}
			type={showPassword ? 'text' : 'password'}
			autoDirection={autoDirection}
			{...props}
			slots={slots}
			slotProps={{
				...slotProps,
				input: {
					...(showPasswordTogglerButtonPosition === 'end'
						? { endAdornment: inputAddorment }
						: { startAdornment: inputAddorment }),
					...slotProps?.input
				}
			}}
		/>
	);
}

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

export default Password;
