import React, { ReactElement } from 'react';
import css from '../../utils/css';

import { CommonProps } from '../common';
import {
  ModalContainer,
  ModalOverlay,
  ModalContentWrapper,
  ModalContent,
  PopUpModalBodyContainer,
  PopUpModalBodyTextWrapper,
  TitleSpacing,
  IconWrapper,
} from './StyledModal';
import { useScrollLock } from './hooks';
import Icon, { IconName } from '../Icon';
import ModalBody from './ModalBody';
import ModalContext from './ModalContext';
import ModalFooter from './ModalFooter';
import Typography from '../Typography';

export interface PopUpModalProps extends CommonProps {
  /**
   * Modal body.
   */
  body?: string | ReactElement;
  /**
   * Whether clicking outside the modal overlap to invoke onClose
   */
  canOutsideClickClose?: boolean;
  /**
   * Modal footer.
   */
  footer?: string | ReactElement;
  /**
   * Closing callback. The callback will be called when user clicks outside of the modal (if canOutsideClickClose is set to true).
   */
  onClose?: () => void;
  /**
   * Open state of modal.
   */
  open?: boolean;
  /**
   * Modal size.
   */
  size?: 'small' | 'medium' | 'large' | 'xlarge';
  /**
   * Modal title.
   */
  title?: string | ReactElement;
  /**
   * Modal type.
   */
  variant?: 'info' | 'success' | 'warning' | 'danger' | 'confirm';
}

type ModalIcon = {
  icon: IconName;
  intent: 'info' | 'success' | 'warning' | 'danger' | 'error';
};

type IconMap = {
  confirm: ModalIcon;
  danger: ModalIcon;
  info: ModalIcon;
  success: ModalIcon;
  warning: ModalIcon;
};

const ICON_MAP: IconMap = {
  info: {
    icon: 'circle-info-outlined',
    intent: 'info',
  },
  success: {
    icon: 'circle-ok-outlined',
    intent: 'success',
  },
  warning: {
    icon: 'circle-warning-outlined',
    intent: 'warning',
  },
  danger: {
    icon: 'circle-warning-outlined',
    intent: 'danger',
  },
  confirm: {
    icon: 'circle-question-outlined',
    intent: 'error',
  },
};

const PopUpModal = ({
  title,
  open = false,
  variant = 'confirm',
  size = 'small',
  onClose,
  canOutsideClickClose = true,
  body,
  footer,
  id,
  className,
  style,
  sx = {},
  'data-test-id': dataTestId,
}: PopUpModalProps): ReactElement => {
  useScrollLock(open);

  const modalIcon = ICON_MAP[variant];
  const modalBody = (
    <PopUpModalBodyContainer>
      <IconWrapper>
        <Icon icon={modalIcon.icon} intent={modalIcon.intent} />
      </IconWrapper>
      <PopUpModalBodyTextWrapper>
        {title !== undefined && (
          <>
            <Typography.Title level={5}>{title}</Typography.Title>
            <TitleSpacing />
          </>
        )}
        {body}
      </PopUpModalBodyTextWrapper>
    </PopUpModalBodyContainer>
  );

  return (
    <ModalContainer
      // FIXME: after consumer correct all usages
      // eslint-disable-next-line no-unneeded-ternary
      themeOpen={open ? true : false}
      id={id}
      className={className}
      style={{ ...style, ...css(sx) }}
      data-test-id={dataTestId}
    >
      <ModalContext.Provider value={{ isPopupModal: true }}>
        <ModalOverlay
          onClick={canOutsideClickClose === true ? onClose : undefined}
        />
        <ModalContentWrapper>
          <ModalContent themeSize={size} data-test-id="modal-content">
            <ModalBody>{modalBody}</ModalBody>
            {footer !== undefined && <ModalFooter>{footer}</ModalFooter>}
          </ModalContent>
        </ModalContentWrapper>
      </ModalContext.Provider>
    </ModalContainer>
  );
};

export default PopUpModal;
