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

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 {
  ThemedModalOverlay,
  FooterWrapper,
  BodyWrapper,
} from "../Modal/ThemedModal";

const HeaderWrapper = styled("div")(props => ({
  display: "flex",
  borderBottom: `${props.theme.borderWidths.xs}px solid ${props.theme.colors.grey.haptik}`,
  // Extra padding on right for the close icon
  padding: "8px 40px 8px 16px",
  fontFamily: "Proxima Nova",
}));

const XDKModalWrapper = styled("div")(props => ({
  fontFamily: "Proxima Nova",
  position: "fixed",
  top: 0,
  left: 0,
  width: "100vw",
  height: "100%",
  zIndex: 1000000009,
  overflow: "hidden",
  pointerEvents: "none",
  display: "flex",
  alignItems: props.fullScreen ? "initial" : "center",
  justifyContent: "flex-start",
  padding: props.fullScreen ? "0px" : "0px 8px",
  marginTop: props.fullScreen ? "65px" : "0px",
}));

const XDKModal = styled("div")(props => ({
  display: "flex",
  opacity: props.active ? "1" : "0",
  flexDirection: "column",
  position: "absolute",
  padding: 0,
  zIndex: 2,
  backgroundColor: props.theme.colors.grey.pastel,
  outline: "none",
  boxShadow: "0px 5px 25px rgba(0, 0, 0, 0.15)",
  boxSizing: "border-box",
  transition: "0.5s cubic-bezier(0.175, 0.5, 0.12, 1)",
  maxWidth: 1200,
  maxHeight: 648,
  borderRadius: props.theme.radii.sm,
  pointerEvents: "auto",
  fontFamily: "Proxima Nova",
  minWidth: props.fullScreen ? "97%" : "90%",
  height: props.fullScreen ? "100%" : props.height,
  justifyContent: "initial",

  // For smaller screens, have to adjust max-height and max-width
  "@media (max-width: 1400px)": {
    maxWidth: "80vw",
  },
}));

const IconWrapper = styled("div")({
  position: "absolute",
  top: 12,
  right: 12,
  padding: 0,
});

const Modal = React.forwardRef((props, ref) => {
  const {
    onClose,
    onEnter,
    children,
    noOverlay,
    active,
    header,
    footer,
    style,
    portalNode: { current: portalNode = null },
    fullScreen,
  } = props;
  const { enabled, visible } = useActivify(active);

  useEscapeKey(onClose);
  useEnterKey(onEnter);

  if (!enabled) return null;
  return (
    <Portal node={portalNode}>
      <XDKModalWrapper data-testid="xdk-modal" fullScreen={fullScreen}>
        {!noOverlay && (
          <ThemedModalOverlay active={visible} onClick={onClose} />
        )}
        <XDKModal active={visible} ref={ref} fullScreen={fullScreen}>
          {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>
          )}
          <IconWrapper data-testid="close-icon">
            <Icon src={CloseV2Icon} onClick={onClose} />
          </IconWrapper>
        </XDKModal>
      </XDKModalWrapper>
    </Portal>
  );
});

Modal.propTypes = {
  /** 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,
  /** 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,
  /** if Modal needs to be loaded to a particular element */
  portalNode: PropTypes.node,
  /** if Modal needs to be loaded on fullscreen */
  fullScreen: PropTypes.bool,
};

Modal.defaultProps = {
  onClose: () => {},
  onEnter: () => {},
  active: false,
  noOverlay: false,
  style: {},
  ref: null,
  portalNode: {
    current: null,
  },
  fullScreen: false,
};

export default Modal;
