import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";

// Internal Components
import Provider from "components/Context/Provider";
import Box from "components/UI/Box";
import Icon from "components/UI/Icon";
import Text from "components/UI/Text";

// Icons
import CloseIcon from "./icons/close.svg";
import SuccessIcon from "./icons/success.svg";

// Constants
import { CONSTANTS } from "./constants";

// Utils
import { getBorderColor, getPositionStyles } from "./utils";

// #region Notification container
const notificationContainerStyles = props => {
  const { theme, type, position, offset, active } = props;

  return {
    position: "fixed",
    width: "fit-content",
    alignItems: "center",
    minWidth: 300,
    maxWidth: 500,
    transition: "all 0.3s ease",
    background: theme.colors.grey.pastel,
    boxShadow: "0px 1px 13px 0px #00000026",
    border: `1px solid ${getBorderColor(type, theme.colors)}`,
    borderRadius: theme.radii.sm,
    marginBottom: theme.space.lg,
    ...getPositionStyles(position, offset, active),
    opacity: active ? 1 : 0,
    zIndex: 9999999999,
  };
};

const NotifyWrapper = styled(Box)(notificationContainerStyles);
// #endregion

// #region Icons within Notification container
const notificationIconStyles = props => {
  const { variant, theme } = props;

  if (variant === "dismiss") {
    return {
      position: "absolute",
      cursor: "pointer",
      top: 8,
      right: 8,
    };
  }

  return {
    cursor: "default",
    width: 42,
    height: 42,
    margin: `0 ${theme.space.sm}px`,
  };
};

const NotificationIcon = styled(Icon)(notificationIconStyles);
// #endregion

const Notification = props => {
  const { TIMEOUT, POSITIONS, CLOSE_ICON_CLASS } = CONSTANTS;
  const [active, setActive] = React.useState(false);
  const {
    title,
    message,
    children,
    type,
    closeable,
    position = POSITIONS.BOTTOM_CENTER,
    offset,
    onDestroy,
    autoDismiss = true,
  } = props;

  const getIcon = () => {
    let icon = null;
    if (type === "success") {
      icon = SuccessIcon;
    }

    return <NotificationIcon src={icon} />;
  };

  const dismissHandler = () => {
    setActive(false);
    if (onDestroy) {
      setTimeout(() => {
        onDestroy();
      }, 100);
    }
  };

  const handleDismiss = () => {
    setTimeout(() => {
      dismissHandler();
    }, TIMEOUT + 300);
  };

  React.useEffect(() => {
    setTimeout(() => setActive(true), 10);

    if (autoDismiss && !closeable) {
      handleDismiss();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <Provider>
      <NotifyWrapper
        active={active}
        type={type}
        position={position}
        offset={offset}
        childrenPresent={children}
        data-testid="notification"
      >
        {getIcon()}
        <Box flexDirection="column">
          <Box
            className={CLOSE_ICON_CLASS}
            onClick={dismissHandler}
            style={{
              padding: "0",
              display: closeable ? "block" : "none",
            }}
          >
            <NotificationIcon src={CloseIcon} variant="dismiss" />
          </Box>
          <Text style={{ paddingRight: 15 }} variant="h3.semi-bold">
            {title}
          </Text>
          {message && (
            <Text variant="body.md" style={{ lineHeight: 1.3 }}>
              {message}
            </Text>
          )}
          {children && <Box padding="10px 0">{children}</Box>}
        </Box>
      </NotifyWrapper>
    </Provider>
  );
};

Notification.propTypes = {
  title: PropTypes.string,
  message: PropTypes.string,
  type: PropTypes.string,
  children: PropTypes.node,
  closeable: PropTypes.bool,
  autoDismiss: PropTypes.bool,
  position: PropTypes.string,
  onDestroy: PropTypes.func,
  offset: PropTypes.shape({
    top: PropTypes.number,
    left: PropTypes.number,
  }),
};

export default Notification;
