import React, { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
import { usePopper } from 'react-popper';
// import { useClickOutside } from '@devesharp/react-hooks/lib/useClickOutside';
import { GetScrollParent } from '@devesharp/react-utils/lib/JSUtils/GetScrollParent';
import Style from './Dropdown.style';

export function useClickOutside(fn: () => void, ref: any): void {
   useEffect(() => {
      function handleClickOutside(event): void {
         if (ref.current && !ref.current.contains(event.target)) {
            fn();
         }
      }

      document.addEventListener('mouseup', handleClickOutside);

      return () => {
         document.removeEventListener('mouseup', handleClickOutside);
      };
   }, [fn]);
}

export interface IPropsDropDown {
   open?: boolean;
   onChange?: (v: any) => void;
   content?: any;
   children?: any;
   placement?:
      | 'auto'
      | 'auto-start'
      | 'auto-end'
      | 'top'
      | 'top-start'
      | 'top-end'
      | 'bottom'
      | 'bottom-start'
      | 'bottom-end'
      | 'right'
      | 'right-start'
      | 'right-end'
      | 'left'
      | 'left-start'
      | 'left-end';
}

export const DropdownBase: React.FunctionComponent<IPropsDropDown> = ({
   open: openProps,
   onChange,
   children,
   content,
   placement = 'bottom-end',
}: IPropsDropDown) => {
   const [_open, _setOpen] = useState(false);
   const open = openProps != undefined ? openProps : _open;
   const setOpen = onChange != undefined ? onChange : _setOpen;

   const dropdownRef = useRef(null);

   const [referenceElement, setReferenceElement] = useState(null);
   const [popperElement, setPopperElement] = useState(null);
   const { styles, attributes } = usePopper(referenceElement, popperElement, {
      placement,
      modifiers: [
         {
            name: 'preventOverflow',
            options: {
               altAxis: false, // false by default
            },
         },
         {
            name: 'offset',
            options: {
               offset: [0, 0],
            },
         },
      ],
   });

   useClickOutside(() => {
      if (open) {
         setTimeout(() => {
            setOpen(false);
         }, 100);
      }
   }, dropdownRef);

   function toggleMenu(): void {
      setOpen(!open);
   }

   /**
    * Envia para posição do datepicker
    */
   useEffect(() => {
      if (open) {
         const el = document.getElementsByClassName('ds-dropdown-base-float')[0];

         const scrollParent = GetScrollParent(dropdownRef.current.parentNode);

         const { top: topMain, height: heightMain } = dropdownRef.current.getBoundingClientRect();
         const { height: heightScroll } = scrollParent.getBoundingClientRect();

         if (topMain + heightMain + el.getBoundingClientRect().height > heightScroll) {
            if (el.scrollIntoView) el.scrollIntoView({ block: 'end', behavior: 'smooth' });
         }
      }
   }, [open]);

   return (
      <Style className="ds-dropdown-base" data-testid="dropdown">
         <div onClick={toggleMenu} ref={setReferenceElement}>
            {children}
         </div>
         {open &&
            ReactDOM.createPortal(
               <Style style={{ display: 'block' }} ref={dropdownRef}>
                  <div
                     className="ds-dropdown-base-float"
                     data-testid="dropmenu-popup"
                     ref={setPopperElement}
                     style={styles.popper}
                     {...attributes.popper}
                  >
                     {content}
                  </div>
               </Style>,
               document.body,
            )}
      </Style>
   );
};
