import React, { useRef, useEffect, InputHTMLAttributes, useImperativeHandle, useCallback, useMemo } from 'react';
import { OnlyNumbers } from '@devesharp/react-utils';
import { useField } from '@unform/core';
import { maskValue } from '../MaskText/mask.utils';
import { IInputProps } from './InputCore.interface';

export const InputCore = React.forwardRef<InputHTMLAttributes<any>, IInputProps>(function InputCore(
   props,
   inputRef: any,
) {
   const ref = useRef();
   useImperativeHandle(inputRef, () => ref.current, []);

   if (props.name) {
      return <InputCoreWithUnform {...props} ref={ref} />;
   }

   return <InputCoreWithoutUnform {...props} ref={ref} />;
});

export const InputCoreWithUnform = React.forwardRef<InputHTMLAttributes<any>, IInputProps>(function InputCoreWithUnform(
   props,
   inputRef: any,
) {
   const ref = useRef<any>();
   useImperativeHandle(inputRef, () => ref.current, []);

   const { fieldName, registerField, defaultValue = null, error, clearError } = useField(props.name);
   // const inputValueRef = useRef(maskValue(defaultValue, props.mask, props as any));

   useEffect(() => {
      registerField({
         name: fieldName,
         ref,
         path: 'current' as any,
         clearValue(_ref) {
            ref.current.value = '';
            // for native
            if (ref.current?.clear) ref.current?.clear();
            ref.current.dispatchEvent(new InputEvent('input', { bubbles: true }));
         },
         setValue(_ref: any, value: string) {
            ref.current.value = maskValue(value, props.mask, props as any);
            ref.current.dispatchEvent(new InputEvent('input', { bubbles: true }));
         },
         getValue(_ref: any) {
            if (props.mask == 'number') {
               if (!ref.current.value || ref.current.value === '') return '';
               return (Number(OnlyNumbers(ref.current.value)) / 10 ** (props.decimals ?? 2)) as any;
            }

            if (props.mask == 'CEP' || props.mask == 'phone' || props.mask == 'CPF') {
               return OnlyNumbers(ref.current.value) as any;
            }
            return ref.current.value;
         },
      });
   }, [fieldName, registerField]);

   const onInput = useCallback(
      function onSelectItem(text: any) {
         // ref.current.value = text;
         if (error) clearError();
         if (props.onInput) props.onInput(text);
      },
      [error],
   );

   // eslint-disable-next-line @typescript-eslint/no-use-before-define
   return (
      <InputCoreWithoutUnform
         {...props}
         ref={ref}
         onInput={onInput}
         value={null}
         error={error}
         defaultValue={defaultValue}
      />
   );
});

export const InputCoreWithoutUnform = React.forwardRef<HTMLInputElement, IInputProps>(function InputCoreWithoutUnform(
   props,
   inputRef: any,
) {
   const ref = useRef(null);
   useImperativeHandle(inputRef, () => ref.current, []);

   const PureComponent = useMemo(() => props.as || 'input', [props.as]) as any;

   return <PureComponent {...props} ref={ref} />;
});
