import React, { useCallback, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { AnimatePresence } from 'framer-motion';
import { bem } from 'utils/bem';
import { ModalContentProps } from './types';
import { ANIMATION } from './constants';
import { Content } from './components';
import { SModal, BEM_CLASS } from './s-modal';

interface ModalProps {
  className?: string;
  isOpened?: boolean;
  isOverlayClosesModal?: boolean;
  renderContent(props: ModalContentProps): React.ReactNode;
  onClose?(): void;
}

const classes = bem(BEM_CLASS);

export const Modal = React.memo(
  ({ className, isOpened = false, isOverlayClosesModal = false, renderContent, onClose }: ModalProps) => {
    const [isModalOpened, setIsModalOpened] = useState(isOpened);

    const closeModal = useCallback(() => {
      setIsModalOpened(false);
      onClose?.();
    }, [onClose]);

    useEffect(() => {
      setIsModalOpened(isOpened);
    }, [isOpened]);

    useEffect(() => {
      document.body.style.overflow = isModalOpened ? 'hidden' : 'visible';

      return () => {
        document.body.style.overflow = 'visible';
      };
    }, [isModalOpened]);

    return createPortal(
      <AnimatePresence exitBeforeEnter>
        {isModalOpened ? (
          <SModal {...ANIMATION} className={className}>
            <button
              tabIndex={-1}
              className={classes('overlay')}
              onClick={isOverlayClosesModal ? closeModal : undefined}
            />

            <div className={classes('content')}>
              <Content isOpened={isModalOpened} closeModal={closeModal}>
                {renderContent({ isOpened: isModalOpened, closeModal })}
              </Content>
            </div>
          </SModal>
        ) : null}
      </AnimatePresence>,
      document.body
    );
  }
);
