import React, { useRef, useEffect, useState, useImperativeHandle, useContext } from 'react';
import { useField } from '@unform/core';
import { useEventListener } from '../../../hooks/useEventListener';
import { OnlyNumbers } from '../../../services/utils.service';
import AppContext from '../../AppProvider/AppContext';
import { maskValue } from '../../MaskText/mask.utils';
import { IPropsInput } from '../input.interface';
import Style from './Input.style';
import { InputPure } from './InputPure';

interface IPropsInputWeb extends IPropsInput {
   theme?: string;
   onEnter?: () => any;
}

export const Input = React.forwardRef<any, IPropsInputWeb>(function Input(props: IPropsInputWeb, ref: any) {
   props = { decimals: 0, ...props };

   const {
      name,
      title,
      textRight = false,
      textCenter = false,
      prefix,
      decimals = 0,
      theme: themeInput,
      suffix,
      loading = false,
      onEnter = () => {},
      number = false,
      withoutDotNumber = false,
      CEP = false,
      CNPJ = false,
      CPF = false,
      RG = false,
      phone = false,
      noSpaces = false,
      as = InputPure,
      ...rest
   } = props;

   // Custom component
   const { pureComponents: { Input: InputComponent = null } = {} } = useContext(AppContext);
   const Component = InputComponent ?? as;

   const inputRef = useRef<any>();

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

   // Se Input está em focus
   const [focus, setFocus] = useState(false);

   // Unform
   const { registerField, defaultValue = '', error, fieldName, clearError } = useField(name);
   const defaultValueInput = maskValue(defaultValue, props);

   // onEnter
   useEventListener('keydown.enter', () => onEnter(), inputRef);

   // Event: Input
   useEventListener(
      'input',
      (evt) => {
         inputRef.current.value = maskValue(inputRef.current.value, props);
         clearError();
      },
      inputRef,
   );

   useEffect(() => {
      registerField({
         name: fieldName,
         ref: inputRef.current,
         path: 'value' as any,
         setValue(_ref: any, value: string) {
            inputRef.current.value = maskValue(value, props);
         },
         getValue(_ref: any) {
            if (number) return OnlyNumbers(_ref.value);
            if (CEP) return OnlyNumbers(_ref.value);
            return _ref.value;
         },
      });
   }, [fieldName, registerField]);

   return (
      <Style themeInput={themeInput}>
         <div className={`input-title ${focus && 'focus'}`}>{title}</div>

         <Component
            inputRef={inputRef}
            textRight={textRight}
            error={error}
            prefix={prefix}
            textCenter={textCenter}
            loading={loading}
            suffix={suffix}
            defaultValueInput={defaultValueInput}
            {...rest}
         />
      </Style>
   );
});
