import React from 'react'
import PropTypes from 'prop-types'
import {
  applyTextStyles,
  getTokensPropType,
  selectSystemProps,
  StackView,
  Typography,
  useTheme,
  useThemeTokens,
  wrapStringsInText
} from '@telus-uds/components-base'
import styled from 'styled-components'
import ItemBase from './ItemBase'
import { htmlAttrs } from '../utils'
import { OL_COUNTER_NAME } from './constants'

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

const selectItemTextStyles = (
  { itemFontWeight, itemFontSize, itemLineHeight, itemFontName, itemColor, itemTextColor },
  themeOptions
) =>
  applyTextStyles({
    fontWeight: itemFontWeight,
    fontSize: itemFontSize,
    fontName: itemFontName,
    color: itemColor || itemTextColor,
    themeOptions,
    lineHeight: itemLineHeight
  })

const StyledItemBase = styled(ItemBase)(
  ({
    interItemMargin,
    itemBulletContainerWidth,
    itemBulletTextAlign,
    itemFontWeight,
    itemFontSize,
    itemFontName,
    itemLineHeight,
    themeOptions,
    listGutter,
    itemColor,
    itemTextColor
  }) => ({
    counterIncrement: OL_COUNTER_NAME,
    '::before': {
      content: `counter(${OL_COUNTER_NAME})'.'`,
      display: 'inline-block',
      color: itemColor || itemTextColor,
      width: itemBulletContainerWidth,
      paddingRight: listGutter,
      textAlign: itemBulletTextAlign,
      flexShrink: 0,
      whiteSpace: 'nowrap',
      overflow: 'hidden',
      ...applyTextStyles({
        fontWeight: itemFontWeight,
        fontSize: itemFontSize,
        fontName: itemFontName,
        themeOptions
      }),
      lineHeight: `${itemLineHeight * itemFontSize}px`
    },
    ':not(:last-child)': { marginBottom: interItemMargin }
  })
)

const ItemContent = styled.div({
  display: 'flex',
  flexDirection: 'column',
  gap: 0
})

const Item = React.forwardRef(
  ({ children, counterName, title, tokens = {}, variant, ...rest }, ref) => {
    // We are reusing some tokens from the list component here in order to provide a unified
    // experience
    const themeTokens = useThemeTokens('OrderedList', tokens, variant)
    const headingTokens = title && {
      lineHeight: themeTokens.itemLineHeight,
      fontSize: themeTokens.itemFontSize,
      color: themeTokens.itemColor || themeTokens.itemTextColor,
      fontName: themeTokens.headerFontName,
      fontWeight: themeTokens.headerFontWeight
    }

    const { themeOptions } = useTheme()
    const itemContent = wrapStringsInText(children, {
      style: selectItemTextStyles(themeTokens, themeOptions)
    })

    return (
      <StyledItemBase ref={ref} themeOptions={themeOptions} {...themeTokens} {...selectProps(rest)}>
        {title ? (
          <StackView tokens={{ flexShrink: 1 }} space={0}>
            <Typography variant={{ size: 'h4' }} tokens={headingTokens}>
              {title}
            </Typography>
            <ItemContent {...themeTokens}>{itemContent}</ItemContent>
          </StackView>
        ) : (
          <ItemContent>{itemContent}</ItemContent>
        )}
      </StyledItemBase>
    )
  }
)

Item.displayName = 'OrderedListItem'

Item.propTypes = {
  ...selectedSystemPropTypes,
  /**
   * Item content
   */
  children: PropTypes.node.isRequired,
  /**
   * Defines the title of the `OrderedList.Item`
   */
  title: PropTypes.string,
  /**
   * Item tokens
   */
  tokens: getTokensPropType('OrderedList')
}

export default Item
