import React, { useCallback, useEffect, useRef, useState } from 'react';
import { useField } from '@unform/core';
import { IPropsButtonsGroup, getValue } from '../ButtonGroup.interface';
import Style 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) {
            const newValue = [...value];

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

            setValue(newValue);
            inputRef.current = 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);
      },
      [onChange, value],
   );

   return (
      <Style>
         {title && <div className="input-title">{title}</div>}
         <div className={`btn-group btn-selects ${!!error && 'has-error'}`}>
            {options &&
               options.map((i) => (
                  <div
                     key={`btn-${i.name}`}
                     className={`btn btn-primary ${
                        (multiSelection ? value.indexOf(i.value) !== -1 : value === i.value) && 'active'
                     }`}
                     onClick={() => select(i.value)}
                     data-testid={`button-${i.name}`}
                  >
                     {i.name}
                  </div>
               ))}
         </div>

         {error && (
            <div className="error-input" data-testid="input-error}">
               {error}
            </div>
         )}
      </Style>
   );
};
