import React, { useEffect, useRef } from 'react';
import DropdownBase, {
  DropdownBaseProps,
} from '@digigov/react-core/DropdownBase';

export * from '@digigov/react-core/DropdownButton';
export * from '@digigov/react-core/DropdownContent';

export interface DropdownProps extends DropdownBaseProps {
  /**
   * Use closeBehaviour to set the way that the Dropdown will close.
   */
  closeBehaviour?: 'clickButton' | 'clickOutside';
  /**
   * Use float dropdown to set the dropdown to float over
   * scroll bars and stay on a static position.
   * This is mainly used to show actions in a long table.
   */
  float?: boolean;
}
/**
 * Dropdown component is used for showing more options with a button.
 */

export const Dropdown = React.forwardRef<HTMLDetailsElement, DropdownProps>(
  function Dropdown(
    { closeBehaviour = 'clickOutside', float = false, ...props },
    ref
  ) {
    const innerRef = useRef<HTMLDetailsElement | null>(null);

    useEffect(() => {
      const element = innerRef.current;
      if (!element) {
        return;
      }
      const keyDownHandler = (event) => {
        if (event.key === 'Escape') {
          element.open = false;
          event.preventDefault();
        }
      };
      const handleClickOutside = (event) => {
        if (element && !element.contains(event.target)) {
          element.open = false;
        }
      };

      if (closeBehaviour === 'clickOutside') {
        document.addEventListener('click', handleClickOutside, true);
      }
      document.addEventListener('keydown', keyDownHandler);
      const toggleFloat = () => {
        const tbody = element.closest('tbody') as HTMLElement;
        const parentElement = element?.parentElement as HTMLElement;
        if (element.open) {
          tbody.style.position = 'inherit';
          const rect = element?.getBoundingClientRect();
          const parentRect = parentElement.getBoundingClientRect();
          const top = rect.top + window.pageYOffset;
          const left = rect.left + window.pageXOffset;
          parentElement.style.height = `${parentRect.height}px`;
          parentElement.style.width = `${parentRect.width}px`;
          element.style.top = `${top}px`;
          element.style.left = `${left}px`;
          element.style.position = `absolute`;
          element.style.display = `block`;
          element.style.background = 'inherit';
        } else {
          tbody.style.position = 'relative';
          parentElement.style.height = '';
          parentElement.style.width = '';
          element.style.top = `0`;
          element.style.left = `0`;
          element.style.position = `relative`;
          element.style.display = `table-cell`;
        }
      };
      if (float) {
        element.addEventListener('toggle', toggleFloat);
      }
      return () => {
        if (closeBehaviour === 'clickOutside') {
          document.removeEventListener('click', handleClickOutside, true);
        }
        if (float) {
          element.removeEventListener('toggle', toggleFloat);
        }
        document.removeEventListener('keydown', keyDownHandler);
      };
    }, []);
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    return (
      <DropdownBase
        ref={(el) => {
          innerRef.current = el;
          if (typeof ref === 'function') {
            ref(el);
          }
        }}
        {...props}
      />
    );
  }
);

export { DropdownBase };
export default Dropdown;
