import React, { useCallback, useEffect, useRef, useState } from 'react';
import { View } from 'react-native';
import { useField } from '@unform/core';
import { Flex } from '../../Flex/native';
import { IPropsButtonsGroup, getValue } from '../ButtonGroup.interface';
import { ButtonText, ButtonsGroupStyle, ButtonComponent, TitleText, TextError } from './ButtonGroup.style';

export const ButtonsGroup: React.FunctionComponent<IPropsButtonsGroup> = ({
   options,
   name,
   title,
   multiSelection = false,
   allowEmpty = false,
   onChange,
   ...rest
}: IPropsButtonsGroup) => {
   const { fieldName, registerField, defaultValue = '', error, clearError } = useField(name);

   const inputRef = useRef(getValue(defaultValue));
   const [value, setValue] = useState(getValue(defaultValue));

   useEffect(() => {
      registerField({
         name: fieldName,
         ref: inputRef,
         path: 'current' as any,
         clearValue(ref) {
            if (multiSelection) {
               ref.current = [];
            } else {
               ref.current = '';
            }

            setValue(ref.current);
         },
         setValue(ref, v) {
            ref.current = v || '';

            if (multiSelection && !(v instanceof Array)) {
               ref.current = [];
            }

            setValue(ref.current);
         },
         getValue(ref) {
            return ref.current;
         },
      });
   }, [fieldName, registerField, value]);

   const select = useCallback((_value: any): void => {
      clearError();

      if (multiSelection) {
         setValue((currentValue) => {
            const newValue = [...currentValue];

            if (newValue.indexOf(_value) === -1) {
               newValue.push(_value);
            } else {
               newValue.splice(newValue.indexOf(_value), 1);
            }

            inputRef.current = newValue;

            return newValue;
         });
      } else if (allowEmpty) {
         inputRef.current = inputRef.current === _value ? null : _value;
         setValue(inputRef.current);
      } else {
         inputRef.current = _value;
         setValue(inputRef.current);
      }

      setTimeout(() => onChange && onChange(inputRef.current), 1);
   }, []);

   return (
      <View>
         {title && <TitleText>{title}</TitleText>}
         <ButtonsGroupStyle horizontal>
            {options &&
               options.map((option) => (
                  <Button
                     select={select}
                     option={option}
                     key={option.value}
                     active={(multiSelection ? value.indexOf(option.value) !== -1 : value === option.value) && 'active'}
                  />
               ))}
         </ButtonsGroupStyle>

         {!!error && <TextError testID="input-error">{error}</TextError>}
      </View>
   );
};

const Button = React.memo(function Button({ option, select, active }: any): JSX.Element {
   return (
      <ButtonComponent
         onPress={() => select(option.value)}
         key={option.value}
         active={active}
         testID={`button-${option.value}`}
      >
         <ButtonText active={active}>{option.name}</ButtonText>
      </ButtonComponent>
   );
});
