import React from 'react'
import PropTypes from 'prop-types'
import {
  selectSystemProps,
  Typography,
  getTokensPropType,
  useThemeTokens
} from '@telus-uds/components-base'
import styled from 'styled-components'
import { htmlAttrs, transformGradient } from '../utils'

const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs])

const BadgeContainer = styled.div`
  background: ${({ background }) => background};
  border: ${({ border }) => border};
  display: inline-flex;
  justify-content: center;
  align-items: center;
  height: fit-content;
  padding: ${({ padding }) => padding};
  border-radius: ${({ radius }) => radius};
  width: fit-content;
  ${({ isOutlineOffer, isAlternative, gradient }) =>
    (isOutlineOffer || isAlternative) &&
    `
    > div {
      background: ${gradient};
	    -webkit-background-clip: text;
	    ${gradient && '-webkit-text-fill-color: transparent;'}
    }`}
`

const fontSizeMapping = {
  12: 'micro',
  14: 'small',
  16: 'h6'
}

const Badge = React.forwardRef(({ children, tokens, variant = {}, ...rest }, ref) => {
  const {
    backgroundColor,
    gradient,
    borderColor,
    borderRadius,
    borderWidth,
    color,
    paddingLeft,
    paddingRight,
    paddingTop,
    paddingBottom,
    fontName,
    fontWeight,
    fontSize
  } = useThemeTokens('Badge', tokens, variant)

  const semanticGradient = gradient && transformGradient(gradient)

  const { outline, purpose, alternative } = variant
  let background = backgroundColor
  const isOutlineOffer = purpose === 'offer' && outline
  if ((isOutlineOffer || alternative) && gradient) {
    background = `linear-gradient(#fff 0 0) padding-box, ${semanticGradient} border-box`
  } else if (purpose === 'offer' && gradient) {
    background = semanticGradient
  }

  return (
    <BadgeContainer
      isOutlineOffer={isOutlineOffer}
      isAlternative={alternative}
      padding={`${paddingTop}px ${paddingRight}px ${paddingBottom}px ${paddingLeft}px`}
      radius={`${borderRadius}px`}
      background={background}
      fontName={fontName}
      fontWeight={fontWeight}
      gradient={semanticGradient}
      border={`${borderWidth}px solid ${borderColor}`}
      ref={ref}
      {...selectProps(rest)}
    >
      <Typography
        tokens={{ fontName, fontWeight, color }}
        variant={{ size: fontSizeMapping[fontSize] }}
      >
        {children}
      </Typography>
    </BadgeContainer>
  )
})

Badge.displayName = 'Badge'

Badge.propTypes = {
  ...selectedSystemPropTypes,
  children: PropTypes.node,
  tokens: getTokensPropType('Badge'),
  variant: PropTypes.exact({
    outline: PropTypes.bool,
    purpose: PropTypes.oneOf(['offer', 'editorial']),
    alternative: PropTypes.bool,
    inverse: PropTypes.bool
  })
}

export default Badge
