import type { FC, HTMLAttributes } from 'react';
import classnames from 'classnames';
import React, { useEffect, useRef } from 'react';
import ClientPortal from '../ClientPortal/ClientPortal';

export interface ModalProps extends HTMLAttributes<HTMLDivElement> {
  centered?: boolean;
  isOpen: boolean;
  toggle: (event: KeyboardEvent | MouseEvent) => void;
}

const Modal: FC<ModalProps> = ({ centered = false, className, isOpen, toggle, ...props }) => {
  const ref = useRef<HTMLDivElement>(null);

  // Close the modal if the Escape key is pressed

  useEffect(() => {
    function handleKeyDown(event: KeyboardEvent) {
      if (isOpen && event.key === 'Escape') {
        toggle(event);
      }
    }

    document.addEventListener('keydown', handleKeyDown);

    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, toggle]);

  // Close the modal if the backdrop is clicked

  useEffect(() => {
    const { current } = ref;

    function handleBackdropClick(event: MouseEvent) {
      if (event.target === ref.current) {
        toggle(event);
      }
    }

    if (current) {
      current.addEventListener('click', handleBackdropClick);
    }

    return () => current?.removeEventListener('click', handleBackdropClick);
  }, [ref, toggle]);

  // Toggle the .modal-open class on the body

  useEffect(() => {
    document.body.classList.toggle('modal-open', isOpen);
  }, [isOpen]);

  return (
    <ClientPortal>
      {isOpen && (
        <div className={classnames('modal', { 'modal-centered': centered })} data-testid="Modal" ref={ref}>
          <div className={classnames('modal-dialog', className)} {...props} />
        </div>
      )}
    </ClientPortal>
  );
};

export default Modal;
