import React from 'react'
import PropTypes from 'prop-types'
import { View, StyleSheet } from 'react-native'

import { getTokensPropType } from '../utils/props/tokens'
import { htmlAttrs } from '../utils/htmlAttrs'
import { selectSystemProps } from '../utils/props/selectSystemProps'
import { variantProp } from '../utils/props/variantProp'
import { viewProps } from '../utils/props/viewProps'
import { wrapStringsInText } from '../utils/children'
import { applyTextStyles } from '../ThemeProvider/utils/styles'
import { useTheme } from '../ThemeProvider/useTheme'
import { useThemeTokens } from '../ThemeProvider/useThemeTokens'
import { Typography } from '../Typography/Typography'
import { OrderedListItemBase } from './OrderedListItemBase'

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

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

const selectItemCounterStyles = ({
  itemBulletContainerWidth,
  itemBulletTextAlign,
  itemFontWeight,
  itemFontSize,
  itemFontName,
  itemLineHeight,
  themeOptions,
  itemColor,
  itemTextColor
}) => ({
  color: itemColor || itemTextColor,
  width: itemBulletContainerWidth,
  textAlign: itemBulletTextAlign,
  ...applyTextStyles({
    fontWeight: itemFontWeight,
    fontSize: itemFontSize,
    fontName: itemFontName,
    themeOptions
  }),
  lineHeight: itemLineHeight * itemFontSize
})

const selectItemContentStyles = ({ interItemMargin, listGutter, ...themeTokens }, isLastChild) => ({
  ...themeTokens,
  marginLeft: listGutter,
  marginBottom: !isLastChild ? interItemMargin : 0
})

export const OrderedListItem = React.forwardRef(
  ({ children, index, isLastChild, title, tokens = {}, variant, ...rest }, ref) => {
    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)
    })
    const itemCounter = wrapStringsInText(`${index}.`, {
      style: selectItemTextStyles(themeTokens, themeOptions)
    })

    return (
      <OrderedListItemBase
        ref={ref}
        style={{ ...staticStyles.container, ...themeTokens }}
        {...selectProps(rest)}
      >
        <View style={[staticStyles.itemCounter, selectItemCounterStyles(themeTokens)]}>
          {itemCounter}
        </View>
        <View style={[staticStyles.itemContent, selectItemContentStyles(themeTokens, isLastChild)]}>
          {title && (
            <View>
              <Typography variant={{ size: 'h4' }} tokens={headingTokens}>
                {title}
              </Typography>
            </View>
          )}
          <View>{itemContent}</View>
        </View>
      </OrderedListItemBase>
    )
  }
)

OrderedListItem.propTypes = {
  ...selectedSystemPropTypes,
  /**
   * Item content
   */
  children: PropTypes.node.isRequired,
  /**
   * Item index
   */
  index: PropTypes.number,
  /**
   * If true, the item is the last one on the list
   */
  isLastChild: PropTypes.bool,
  /**
   * Defines the title of the `OrderedListItem`
   */
  title: PropTypes.string,
  /**
   * Item tokens
   */
  tokens: getTokensPropType('OrderedList'),
  /**
   * Item variant
   */
  variant: variantProp.propType
}

OrderedListItem.displayName = 'OrderedListItem'

const staticStyles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row'
  },
  itemCounter: {
    alignItems: 'flex-end'
  },
  itemContent: {
    flexShrink: 1
  }
})
