import React, {
   useRef,
   useEffect,
   InputHTMLAttributes,
   useState,
   useImperativeHandle,
   useCallback,
   useMemo,
} from 'react';
import { useField } from '@devesharp/unform-core';
import isEqual from 'lodash/isEqual';
import { IRadioProps } from './Radio.interface';

const ReactNative = typeof navigator !== 'undefined' && navigator?.product === 'ReactNative';

export const RadioCore = React.forwardRef<InputHTMLAttributes<any>, IRadioProps>(function RadioCore(
   props,
   inputRef: any,
) {
   if (props.name) {
      return <RadioCoreWithUnform {...props} ref={inputRef} />;
   }

   return <RadioCoreWithoutUnform {...props} ref={inputRef} value={props.value ?? null} />;
});

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

   const { fieldName, registerField, defaultValue = null, error, clearError } = useField(props.name);
   const inputValueRef = useRef(defaultValue);
   const [value, setValue] = useState<any>(ReactNative ? defaultValue : undefined);

   useEffect(() => {
      registerField({
         name: fieldName,
         ref: inputValueRef,
         path: 'current' as any,
         clearValue(_ref) {
            _ref.current = null;

            if (ReactNative) {
               setValue(null);
            }
         },
         setValue(_ref, v) {
            _ref.current = v;
            const index = props.options.findIndex((i) => isEqual(i.value, v));

            if (ReactNative) {
               setValue(v);
            } else if (index != -1) {
               ref.current[index].checked = true;
            }
         },
         getValue(_ref) {
            return _ref.current;
         },
      });
   }, [fieldName, registerField, props.options]);

   const onChange = useCallback(
      function onSelectItem(newValue: any) {
         if (error) clearError();
         inputValueRef.current = newValue;
         if (ReactNative) {
            setValue(newValue);
         }
         if (props.onChange) props.onChange(newValue);
      },
      [error],
   );

   return (
      <RadioCoreWithoutUnform
         {...props}
         ref={ref}
         onChange={onChange}
         value={value}
         error={error}
         defaultValue={defaultValue}
      />
   );
});

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

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

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