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 { OrderedListItemBase } from './OrderedListItemBase'
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(OrderedListItemBase)(
  ({
    $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: $themeOptions
      }),
      lineHeight: `${$itemLineHeight * $itemFontSize}px`
    },
    '&:not(:last-child)': { marginBottom: $interItemMargin }
  })
)

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

export const OrderedListItem = 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}
        $interItemMargin={themeTokens.interItemMargin}
        $itemBulletContainerWidth={themeTokens.itemBulletContainerWidth}
        $itemBulletTextAlign={themeTokens.itemBulletTextAlign}
        $itemFontWeight={themeTokens.itemFontWeight}
        $itemFontSize={themeTokens.itemFontSize}
        $itemFontName={themeTokens.itemFontName}
        $itemLineHeight={themeTokens.itemLineHeight}
        $listGutter={themeTokens.listGutter}
        $itemColor={themeTokens.itemColor}
        $itemTextColor={themeTokens.itemTextColor}
        {...selectProps(rest)}
      >
        {title ? (
          <StackView tokens={{ flexShrink: 1 }} space={0}>
            <Typography variant={{ size: 'h4' }} tokens={headingTokens}>
              {title}
            </Typography>
            <ItemContent>{itemContent}</ItemContent>
          </StackView>
        ) : (
          <ItemContent>{itemContent}</ItemContent>
        )}
      </StyledItemBase>
    )
  }
)

OrderedListItem.displayName = 'OrderedListItem'

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