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

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

const StyledSpan = styled.span`
  ${({ $flex }) => ($flex ? 'display: inline-flex;' : '')}
`

/**
 * Text as an HTML ```<span>``` element.
 *
 * Span may be used in cases where an inline span or direct access to HTML attributes is required.
 * In most cases, `Typography` should be used for text, or Paragraph for body text.
 */
export const Span = React.forwardRef(
  ({ children, variant, tokens, testID, flex, ...rest }, ref) => {
    const style = useTypographyTheme(
      { ...variant, color: variant?.color || variant?.colour },
      tokens
    )
    return (
      <StyledSpan data-testid={testID} $flex={flex} style={style} ref={ref} {...selectProps(rest)}>
        {children}
      </StyledSpan>
    )
  }
)

Span.displayName = 'Span'

Span.propTypes = {
  ...selectedSystemPropTypes,
  children: PropTypes.node.isRequired,
  /**
   * Adds `data-testid` attribute for testing
   */
  testID: PropTypes.string,
  /**
   * Sets display to inline-flex so that children are laid out using the flex model.
   * Use this if the span contains children that expect to be inside a flex container.
   */
  flex: PropTypes.bool,
  /**
   * Span takes the same tokens overrides as Typography
   */
  tokens: getTokensPropType('Typography'),
  /**
   * Span can take any of Typography's theme variants
   */
  variant: PropTypes.exact({
    bold: PropTypes.bool,
    color: PropTypes.oneOf(['secondary', 'tertiary']),
    /** @deprecated Use `color` instead */
    colour: PropTypes.oneOf(['secondary', 'tertiary']),
    compact: PropTypes.bool,
    inverse: PropTypes.bool,
    size: PropTypes.oneOf([
      'micro',
      'small',
      'large',
      'eyebrow',
      'h1',
      'h2',
      'h3',
      'h4',
      'h5',
      'h6',
      'display1',
      'display2'
    ]),
    weight: PropTypes.oneOf(['semibold', 'bold'])
  })
}
