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

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

const StyledOrderedListBase = styled(OrderedListBase)(({ start }) => ({
  // Using CSS counters here to have better control over the number styling
  listStyle: 'none',
  counterReset: `${OL_COUNTER_NAME} ${start - 1}`
}))

/**
 * Themed semantic ordered list.
 */
const OrderedList = React.forwardRef(
  ({ children, start = 1, variant = {}, tokens = {}, ...rest }, ref) => {
    // Check if children is an array
    const isChildrenArray = Array.isArray(children)

    // Pass any variants and tokens "OrderedList" receives down to the individual list items.
    const childrenWithParentVariantsAndTokens = React.useMemo(() => {
      const addVariantAndTokensToProps = (child) => {
        const existingChildVariants = child.props?.variant ?? {}
        const existingChildTokens = child.props?.tokens ?? {}

        return React.cloneElement(child, {
          variant: { ...existingChildVariants, ...variant },
          tokens: { ...existingChildTokens, ...tokens }
        })
      }

      if (variant || tokens) {
        if (isChildrenArray) {
          return children.map(addVariantAndTokensToProps)
        }
        return [addVariantAndTokensToProps(children)]
      }

      return children
    }, [children, variant, isChildrenArray, tokens])

    return (
      <StyledOrderedListBase {...selectProps(rest)} ref={ref} start={start}>
        {childrenWithParentVariantsAndTokens}
      </StyledOrderedListBase>
    )
  }
)
OrderedList.displayName = 'OrderedList'

OrderedList.propTypes = {
  ...selectedSystemPropTypes,
  /**
   * A list of ordered items wrapped in `OrderedList.Item`.
   */
  children: PropTypes.node.isRequired,
  /**
   * The position to start the list with.
   */
  start: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  variant: variantProp.propType,
  tokens: getTokensPropType('OrderedList')
}

OrderedList.Item = Item

export default OrderedList
