import React from 'react'
import { View, Platform, StyleSheet } from 'react-native'
import PropTypes from 'prop-types'
import { a11yProps } from '../utils/props/a11yProps'
import { getTokensPropType } from '../utils/props/tokens'
import { selectSystemProps } from '../utils/props/selectSystemProps'
import { variantProp } from '../utils/props/variantProp'
import { viewProps } from '../utils/props/viewProps'
import { unpackFragment } from '../utils/children'

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

const LIST_ITEM_TYPE = 'ListItem'
const LINKS_ITEM_TYPE = 'LinksItem'

const isListItem = (element) => {
  if (!element?.type) return false

  if (element.type.__UDS_COMPONENT_TYPE__ === LIST_ITEM_TYPE) {
    return true
  }

  const elementName = element.type.displayName || element.type.name || ''
  return (
    elementName === LIST_ITEM_TYPE ||
    elementName.includes(LIST_ITEM_TYPE) ||
    elementName.includes(LINKS_ITEM_TYPE)
  )
}

/**
 * An unordered List component has a child a ListItem that
 * allows icon, dividers and customized typography
 */
export const List = React.forwardRef(
  (
    {
      children,
      showDivider,
      tokens,
      variant,
      iconVerticalAlign,
      accessibilityRole = Platform.select({ web: 'list', default: undefined }),
      ...rest
    },
    ref
  ) => {
    const listChildren = React.Children.toArray(unpackFragment(children))
    const items = listChildren.map((child, index) => {
      if (isListItem(child)) {
        const childProps = {
          tokens,
          variant,
          ...child.props,
          showDivider,
          isLastItem: index + 1 === listChildren.length
        }

        if (!child.props.iconVerticalAlign && iconVerticalAlign) {
          childProps.iconVerticalAlign = iconVerticalAlign
        }

        return React.cloneElement(child, childProps)
      }
      return child
    })

    const content = (
      <View
        style={styles.list}
        accessibilityRole={accessibilityRole}
        ref={ref}
        {...selectProps(rest)}
      >
        {items}
      </View>
    )

    return Platform.OS === 'web' ? <div style={styles.container}>{content}</div> : content
  }
)

const styles = StyleSheet.create({
  container: {
    display: 'block'
  },
  list: {
    flex: 1,
    flexShrink: 1
  }
})

List.displayName = 'List'

List.propTypes = {
  ...selectedSystemPropTypes,
  tokens: getTokensPropType('List'),
  variant: variantProp.propType,
  /**
   * Items rendered in the list.
   */
  children: PropTypes.node,
  /**
   * In case it is not the last item allow display divider
   */
  showDivider: PropTypes.bool,
  /**
   * The vertical alignment of the icon in ListItems.
   * This prop is passed down to ListItem components and can be overridden in individual ListItem components.
   */
  iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom'])
}
