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 StyledParagraph = styled.p`
  ${({ align }) => (align ? `text-align: ${align};` : '')}
  ${({ linesBetween }) => `
    margin-block-start: ${linesBetween}em;
    margin-block-end: ${linesBetween}em;
  `}
  &:first-child {
    margin-block-start: 0em;
  }
  &:last-child {
    margin-block-end: 0em;
  }
`

/**
* Block text as an HTML ```<p>``` element.
	*
	* ##Usage criteria
	*
	* - All body text should be contained in a **Paragraph**, regardless of length.
	* - If the Paragraph is on a dark background, variant **{ invert: true }** must be used to maintain sufficient colour
	contrast.
	* - All Allium Typography variants other than header size variants are supported.
	*/
const Paragraph = React.forwardRef(
  ({ children, variant, tokens, testID, align, linesBetween = 1, ...rest }, ref) => {
    const style = useTypographyTheme(variant, tokens)
    return (
      <StyledParagraph
        ref={ref}
        linesBetween={linesBetween}
        data-testid={testID}
        align={align}
        style={style}
        {...selectProps(rest)}
      >
        {children}
      </StyledParagraph>
    )
  }
)

Paragraph.displayName = 'Paragraph'

Paragraph.propTypes = {
  ...selectedSystemPropTypes,
  children: PropTypes.node.isRequired,
  /**
   * Adds a `data-testid` attribute to the element for testing purposes
   */
  testID: PropTypes.string,
  /**
   * Sets the alignment style for the paragraph. Same options as Typography's `align` prop.
   * 'justify' should be avoided as it usually reduces ease of reading.
   */
  align: PropTypes.oneOf(['auto', 'left', 'right', 'center', 'justify']),
  /**
   * How much space between consecutive paragraphs, or between a paragraph and its siblings, in CSS
   * `em` units: 1 gives space equal to one line of paragraph text, 0.5 would be half a line, etc.
   * @default 1
   */
  linesBetween: PropTypes.number,
  /**
   * Paragraph takes the same tokens overrides as Typography
   */
  tokens: getTokensPropType('Typography'),
  /**
   * Paragraph takes any of Typography's theme variants except for header sizes
   */
  variant: PropTypes.exact({
    bold: PropTypes.bool,
    colour: PropTypes.oneOf(['secondary', 'tertiary']),
    inverse: PropTypes.bool,
    size: PropTypes.oneOf(['micro', 'small', 'large'])
  })
}

export default Paragraph
