import { forwardRef, useLayoutEffect } from 'react';
import { GlobalStyles, InputBaseComponentProps, TextField, TextFieldProps } from '@mui/material';
import clsx from 'clsx';
import InputNumber, { InputNumberProps, ValueType } from 'rc-input-number';

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

export type NumberFieldProps<T extends ValueType = ValueType> = Omit<
	TextFieldProps,
	'select' | 'children' | 'multiline' | 'maxRows' | 'minRows' | 'rows' | 'onChange' | 'value' | 'type'
> &
	Pick<
		InputNumberProps<T>,
		| 'formatter'
		| 'parser'
		| 'decimalSeparator'
		| 'precision'
		| 'step'
		| 'min'
		| 'max'
		| 'pattern'
		| 'value'
		| 'onChange'
		| 'stringMode'
		| 'controls'
		| 'upHandler'
		| 'downHandler'
		| 'keyboard'
		| 'changeOnWheel'
		| 'onInput'
		| 'onPressEnter'
		| 'onStep'
		| 'changeOnBlur'
		| 'prefixCls'
	>;

function NumberField<T extends ValueType>(inProps: NumberFieldProps<T>) {
	const {
		/** RCInputNumberProps */
		formatter,
		parser,
		decimalSeparator,
		precision,
		step,
		min,
		max,
		pattern,
		stringMode,
		controls = false,
		upHandler,
		downHandler,
		keyboard = false,
		changeOnWheel = false,
		onInput,
		onPressEnter,
		onStep,
		changeOnBlur,
		prefixCls,
		/** RCInputNumberProps */

		value,
		onChange,
		inputMode = 'decimal',
		slotProps,
		...props
	} = useDefaultProps({ name: 'RemateNumberField', props: inProps });

	return (
		<TextField
			value={value ?? ''}
			onChange={onChange as any}
			fullWidth
			{...props}
			inputMode={inputMode}
			slotProps={{
				...slotProps,
				input: {
					...slotProps?.input,
					inputComponent: RCNumberInput as any,
					inputProps: {
						formatter,
						parser,
						decimalSeparator,
						precision,
						step,
						inputMode,
						min,
						max,
						pattern,
						stringMode,
						dir: 'ltr',
						controls,
						upHandler,
						downHandler,
						keyboard,
						changeOnWheel,
						onInput,
						onPressEnter,
						onStep,
						changeOnBlur,
						prefixCls,
						...(slotProps as any)?.input?.inputProps
					}
				}
			}}
		/>
	);
}

const RCNumberInput = forwardRef<InputBaseComponentProps, InputNumberProps>(function RCNumberInput(
	{ className, ...props },
	ref
) {
	useLayoutEffect(() => {
		const input = document.getElementById(props.id!);

		if (input) {
			input.className = clsx(input.className, className);
		}
	}, [className, props.id]);

	return (
		<>
			<GlobalStyles
				styles={{
					'.rc-input-number, .rc-input-number-input-wrap': {
						all: 'inherit',
						padding: 'unset',
						backgroundColor: 'unset',
						margin: 'unset'
					}
				}}
			/>

			<InputNumber
				{...props}
				ref={ref as any}
			/>
		</>
	);
});

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

export default NumberField;
