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

import { mergeProps } from '../Util';
import colors from '../Colors';
import { useTheme, styled } from '../Theme';

const types = {
  error: {
    color: colors.common.white,
    backgroundColor: colors.error.main,
  },
  warning: {
    color: colors.common.white,
    backgroundColor: colors.warning.main,
  },
  success: {
    color: colors.common.white,
    backgroundColor: colors.success.main,
  },
  primary: {
    color: colors.common.white,
    backgroundColor: colors.primary.main,
  },
  reverse: {
    color: '#fff',
    backgroundColor: '#222',
  },
};

/**
 * @typedef {import('@mui/material/Typography').TypographyProps} TypographyProps
 * @typedef {{
 *  type?: 'error' | 'warning' | 'success' | 'primary' | 'reverse',
 *  content?: string,
 *  className?: string;
 *  children: import('react').ReactNode,
 *  style?: import('react').CSSProperties
 * }} TagOwnProps
 * @typedef { TypographyProps & TagOwnProps} TagProps
 */

/**
 * @description
 * @param {TagProps} props
 * @return {JSX.Element}
 */
function Tag({ ...rawProps }) {
  const props = Object.assign({}, rawProps);
  if (isUndefined(props.type)) {
    props.type = 'primary';
  }
  if (isUndefined(props.content)) {
    props.content = '';
  }
  if (isUndefined(props.style)) {
    props.style = {};
  }
  if (isUndefined(props.className)) {
    props.className = '';
  }
  const newProps = mergeProps(props, Tag, ['style']);
  const { type, content, children, style, className, ...rest } = newProps;

  const { palette } = useTheme();

  const styles = Object.assign({}, types[type] || types.primary, style);

  if (palette[type]) {
    Object.assign(styles, {
      color: palette[type].contrastText || colors.common.white,
      backgroundColor: palette[type].main,
    });
  }

  return (
    <Span component="span" className={className} style={styles} {...rest}>
      {content || children}
    </Span>
  );
}

Tag.propTypes = {
  children: PropTypes.any.isRequired,
  type: PropTypes.oneOf(Object.keys(types)),
  content: PropTypes.string,
  className: PropTypes.string,
  style: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
};

export default Tag;

const Span = styled(Typography)`
  && {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    padding: 2px 10px;
    height: 20px;
    line-height: 20px;
    font-size: 12px;
    font-weight: 500;
    border-radius: ${({ theme }) => theme.shape.borderRadius * 0.5}px;
  }
`;
