import { ReactNode, useCallback, useEffect, useRef, useState } from "react";
import styles from "./styles.module.css";

interface ModalProps {
  children: ReactNode;
  open?: boolean;
  isCloseButtonVisible?: boolean;
  className?: string;
  containerClassName?: string;
  type?: "hidden" | "normal";
  onClose: () => void;
  removeNoScroll?: boolean;
}

function Modal({
  open,
  children,
  isCloseButtonVisible = true,
  className = "",
  containerClassName = "",
  type = "normal",
  onClose,
  removeNoScroll = true
}: ModalProps): JSX.Element {
  const modalContentRef = useRef<HTMLDivElement>(null);

  const handleClose = (event: React.MouseEvent) => {
    if (event.target !== event.currentTarget) return;
    document.body.classList.remove("no-scroll");
    onClose?.();
  };

  useEffect(() => {
    if (!removeNoScroll) {
      return;
    }

    if (open) {
      document.body.classList.add("no-scroll");
    }

    return () => {
      document.body.classList.remove("no-scroll");
    };
  }, [open, removeNoScroll]);

  const [position, setPosition] = useState({ top: 0, left: 0 });

  const getModalContentPosition = useCallback(() => {
    const modalContent = modalContentRef.current;
    if (!modalContent) return {
      top: 0,
      left: 0
    };
    const { top, left } = modalContent.getBoundingClientRect();
    return { top, left };
  }, [modalContentRef]);

  useEffect(() => {
    const updatePosition = () => {
      requestAnimationFrame(() => {
        setPosition(getModalContentPosition());
      });
    };

    if (open) {
      updatePosition();
    }

    window.addEventListener('resize', updatePosition);

    return () => {
      window.removeEventListener('resize', updatePosition);
    };
  }, [getModalContentPosition, open]);

  if (!open && type === "normal") return <></>;

  return (
    <div
      className={`${styles.modal} ${className} ${type === "hidden" && !open ? styles.hidden : ""
        }`}
      onClick={handleClose}
    >
      {isCloseButtonVisible && (
        <button className={styles["modal-close-btn"]} onClick={handleClose}
          style={{
            top: `${position.top + 16}px`,
            left: `${position.left + 15}px`
          }}
        />
      )}
      <div className={`${styles["modal-content"]} ${containerClassName}`} ref={modalContentRef}>
        {children}
      </div>
    </div>
  );
}

export default Modal;
