import PropTypes from 'prop-types';
import { Typography } from '@mui/material';
import { blueGrey } from '@mui/material/colors';
import isUndefined from 'lodash/isUndefined';

import Icon from '../Icon';
import { mergeProps } from '../Util';
import colors from '../Colors';
import { styled } from '../Theme';
import { withDeprecated } from '../Util/deprecate';

const types = {
  error: {
    icon: 'exclamation-circle',
    color: colors.error.main,
    borderColor: '#e35b54',
    backgroundColor: 'rgba(227, 91, 84, 0.2)',
    variant: 'solid',
  },
  warning: {
    icon: 'exclamation-triangle',
    color: colors.warning.main,
    borderColor: '#f7d040',
    backgroundColor: 'rgba(247, 208, 64, 0.2)',
    variant: 'solid',
  },
  success: {
    icon: 'check-circle',
    color: colors.success.main,
    borderColor: '#89ddd9',
    backgroundColor: 'rgba(137, 221, 217, 0.2)',
  },
  tip: {
    icon: 'info-circle',
    color: colors.grey[500],
    borderColor: '#222222',
    backgroundColor: '#EEEEEE',
    variant: 'solid',
  },
};

/**
 * Alert notification component
 * @typedef {{
 *  type?: 'error' | 'warning' | 'success' | 'tip';
 *  children: any;
 *  className?: string;
 *  style?: object | string;
 *  variant?: 'border' | 'icon';
 * } & import('react').ComponentPropsWithoutRef<"div"> } AlertProps
 */

/**
 * Alert notification component
 * @param {AlertProps} props
 * @returns {JSX.Element}
 */
function Alert({ ...rawProps }) {
  const props = Object.assign({}, rawProps);
  if (isUndefined(props.type)) {
    props.type = 'tip';
  }
  if (isUndefined(props.className)) {
    props.className = '';
  }
  if (isUndefined(props.style)) {
    props.style = {};
  }
  if (isUndefined(props.variant)) {
    props.variant = 'border';
  }
  /** @type {AlertProps} */
  const newProps = mergeProps(props, Alert, ['style']);
  const { type, children, style, className, variant, showIcon = false, ...rest } = newProps;
  const { icon, color, backgroundColor, borderColor, variant: iconVariant } = types[type] || types.success;

  /** @type {import('react').CSSProperties} */
  const styles = Object.assign(
    {
      color: blueGrey[500],
      backgroundColor: variant === 'border' ? backgroundColor : 'transparent',
      borderLeft: variant === 'border' ? `5px solid ${borderColor}` : 'none',
    },
    style
  );

  return (
    <Container {...rest} className={`alert alert--${type} alert--${variant} ${className}`.trim()} style={styles}>
      {(variant === 'icon' || showIcon) && (
        <Icon className="alert-icon" name={icon} size={24} color={color} variant={iconVariant} />
      )}
      <Typography component="div" className="alert-content">
        {children}
      </Typography>
    </Container>
  );
}

Alert.propTypes = {
  type: PropTypes.oneOf(Object.keys(types)),
  children: PropTypes.any.isRequired,
  className: PropTypes.string,
  style: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
  variant: PropTypes.oneOf(['border', 'icon']),
};

export default withDeprecated(Alert, { name: 'Alert', alternative: '@mui/material/Alert' });

const Container = styled('div')`
  display: flex;
  align-items: center;
  font-size: 16px;
  margin: 0;
  padding: 16px;
  margin: 16px 0;

  strong {
    margin: 0 5px;
  }

  .alert-icon {
    margin-right: 16px;
  }

  .alert-content {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
`;
