import React from "react";
import { Portal } from "react-portal";
import PropTypes from "prop-types";

import useActivify from "@src/hooks/useActivify";
import useEscapeKey from "@src/hooks/useEscapeKey";
import useEnterKey from "@src/hooks/useEnterKey";

import Icon from "@src/components/UI/Icon";

import CloseV2Icon from "@src/icons/close-v2.svg";

import {
  ThemedModalWrapper,
  ThemedModalOverlay,
  ThemedModal,
  ThemedIconWrapper,
  HeaderWrapper,
  FooterWrapper,
  BodyWrapper,
} from "./ThemedModal";

import styles from "./Modal.scss";
import ModalHeader from "./components/ModalHeader";

const Modal = React.forwardRef((props, ref) => {
  const {
    themed,
    onClose,
    onEnter,
    className,
    children,
    noOverlay,
    active,
    prefixClassName,
    header,
    footer,
    style,
  } = props;
  const { enabled, visible } = useActivify(active);
  const activeClassName = visible ? styles.modalActive : "";

  useEscapeKey(onClose);
  useEnterKey(onEnter);

  if (!enabled) return null;

  if (themed) {
    return (
      <Portal>
        <ThemedModalWrapper data-testid="modal">
          {!noOverlay && (
            <ThemedModalOverlay active={visible} onClick={onClose} />
          )}
          <ThemedModal active={visible} ref={ref}>
            {header && (
              <HeaderWrapper data-testid="modal-header">{header}</HeaderWrapper>
            )}
            <BodyWrapper
              data-testid="modal-body"
              isHeader={header}
              isFooter={footer}
              style={style}
            >
              {children}
            </BodyWrapper>
            {footer && (
              <FooterWrapper data-testid="modal-footer">{footer}</FooterWrapper>
            )}
            <ThemedIconWrapper data-testid="modal-close-icon">
              <Icon src={CloseV2Icon} onClick={onClose} />
            </ThemedIconWrapper>
          </ThemedModal>
        </ThemedModalWrapper>
      </Portal>
    );
  }

  return (
    <Portal>
      <div
        data-testid="modal"
        className={`${styles.modalWrapper} ${prefixClassName} ${className}`}
      >
        {noOverlay ? null : (
          <div
            className={`${styles.modalOverlay} ${activeClassName} ${prefixClassName}-overlay`}
            onClick={onClose}
          />
        )}
        <div
          className={`${styles.modal} ${activeClassName} ${prefixClassName}-body`}
        >
          {children}
        </div>
      </div>
    </Portal>
  );
});

Modal.Header = ModalHeader;

Modal.propTypes = {
  /** Whether you want to render the new modal */
  themed: PropTypes.bool,
  /** The content you want to render inside the modal */
  children: PropTypes.node,
  /** When the modal closes, this is the callback function called */
  onClose: PropTypes.func,
  /** When the enter button is pressed, this function is called */
  onEnter: PropTypes.func,
  /** Whether the modal is visible or not */
  active: PropTypes.bool,
  /** The className applied to the outermost div of the element */
  className: PropTypes.string,
  /** The prefixClassName appended to all the layers */
  prefixClassName: PropTypes.string,
  /** If true, doesnt render the overlay (transparent) */
  noOverlay: PropTypes.bool,
  /** Header for Themed Modal */
  header: PropTypes.node,
  /** Footer for Themed Modal */
  footer: PropTypes.node,
  /** Style Prop */
  style: PropTypes.object,
  /** Ref to be assigned to Modal */
  ref: PropTypes.any,
};

Modal.defaultProps = {
  themed: false,
  onClose: () => {},
  onEnter: () => {},
  active: false,
  className: "",
  prefixClassName: "",
  noOverlay: false,
  style: {},
  ref: null,
};

Modal.classNames = {
  $prefix: "The main wrapper inside the portal",
  "$prefix-overlay": "The overlay covering the page",
  "$prefix-body": "The actual modal itself",
};

export default Modal;
