import React, { memo, useRef } from 'react';
import {
  FormControl,
  IInputProps,
  Input as InputNB,
  WarningOutlineIcon,
} from 'native-base';
import type { Mask } from '../Masks/formatWithMask.types';
import maskField from '../Masks/maskField';

interface InputProps extends IInputProps {
  name: string;
  label: string;
  errorInfo?: string | string[];
  isRequired?: boolean;
  mask?: Mask | ((text: string) => Mask);
  initialValue?: string;
  setFieldValue: any;
  setFieldTouched: any;
  touched?: boolean;
  maskLength?: number;
  ErrorBox?: (errorInfo: any) => JSX.Element;
}

const Input = ({
  name,
  label,
  errorInfo,
  isRequired = true,
  setFieldValue,
  mask,
  initialValue,
  setFieldTouched,
  touched,
  maskLength,
  ErrorBox,
  ...rest
}: InputProps) => {
  const refValue = useRef(maskField({ text: initialValue, mask }).masked);

  const handleOnChangeText = (text: string) => {
    const hardValue = maskField({
      text,
      mask,
    }).unmasked;

    if (maskLength) {
      const { masked } = maskField({
        text: hardValue.slice(0, maskLength),
        mask,
      });
      refValue.current = masked;
    } else {
      const { masked } = maskField({
        text: hardValue,
        mask,
      });
      refValue.current = masked;
    }
  };
  return (
    <FormControl isRequired={isRequired} isInvalid={!!errorInfo && !!touched}>
      <FormControl.Label>{label}</FormControl.Label>

      <InputNB
        onChangeText={(text) => {
          handleOnChangeText(text);
          setFieldValue(name, text);
        }}
        onBlur={() => setFieldTouched(name)}
        value={refValue.current}
        {...rest}
      />

      {touched && errorInfo ? (
        ErrorBox ? (
          ErrorBox(errorInfo)
        ) : typeof errorInfo === 'string' ? (
          <FormControl.ErrorMessage leftIcon={<WarningOutlineIcon size="xs" />}>
            {errorInfo}
          </FormControl.ErrorMessage>
        ) : (
          errorInfo.map((error) => {
            return (
              <FormControl.ErrorMessage
                leftIcon={<WarningOutlineIcon size="xs" />}
              >
                {error}
              </FormControl.ErrorMessage>
            );
          })
        )
      ) : (
        <FormControl.HelperText>&nbsp;</FormControl.HelperText>
      )}
    </FormControl>
  );
};

export default memo(Input);
