import React from 'react'
import PropTypes from 'prop-types'

import { Pressable, StyleSheet, Platform } from 'react-native'

import { resolvePressableTokens } from '../utils/pressability'
import { clickProps } from '../utils/props/clickProps'
import { linkProps } from '../utils/props/linkProps'
import { hrefAttrsProp } from '../utils/props/hrefAttrsProp'
import { selectTokens } from '../utils/props/tokens'
import { withLinkRouter } from '../utils/withLinkRouter'

import { ListItemBase } from './ListItemBase'
import { ListItemContent } from './ListItemContent'
import { ListItemMark } from './ListItemMark'

const selectPressableStyles = ({
  backgroundColor,
  itemFontColor,
  paddingLeft,
  paddingRight,
  paddingTop,
  paddingBottom,
  interItemMargin
}) => ({
  backgroundColor,
  itemFontColor,
  paddingLeft,
  paddingRight,
  paddingTop,
  paddingBottom,
  marginBottom: interItemMargin,
  ...Platform.select({ web: { outline: 'none' } })
})

const PressableListItemBaseInner = React.forwardRef(
  ({ href, tokens, icon, children, listItemRef, ...rest }, ref) => {
    const { onPress, ...props } = clickProps.toPressProps(rest)
    const { hrefAttrs, rest: listItemProps } = hrefAttrsProp.bundle(props)
    const handlePress = linkProps.handleHref({ href, onPress })

    const listItemTokens = selectTokens('List', typeof tokens === 'function' ? tokens() : tokens)

    return (
      <ListItemBase ref={listItemRef} tokens={listItemTokens} {...listItemProps}>
        {({ isLastItem }) => {
          const getTokens = (pressableState) =>
            resolvePressableTokens(tokens, pressableState, { last: isLastItem })
          const getPressableStyle = (pressableState) => [
            staticStyles.itemContainer,
            selectPressableStyles(getTokens(pressableState))
          ]
          return (
            <Pressable
              onPress={handlePress}
              href={href}
              hrefAttrs={hrefAttrs}
              style={getPressableStyle}
              ref={ref}
            >
              {(pressableState) => {
                const themeTokens = getTokens(pressableState)
                return (
                  <>
                    <ListItemMark icon={icon} tokens={themeTokens} />
                    <ListItemContent tokens={themeTokens}>
                      {typeof children === 'function' ? children(pressableState) : children}
                    </ListItemContent>
                  </>
                )
              }}
            </Pressable>
          )
        }}
      </ListItemBase>
    )
  }
)

PressableListItemBaseInner.displayName = 'PressableListItemBase'

const staticStyles = StyleSheet.create({
  itemContainer: {
    flexDirection: 'row',
    flex: 1
  }
})

PressableListItemBaseInner.propTypes = {
  ...withLinkRouter.propTypes,
  href: PropTypes.string,
  onPress: PropTypes.func,
  // eslint-disable-next-line react/forbid-prop-types
  tokens: PropTypes.any,
  icon: PropTypes.elementType,
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
  listItemRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.any })])
}

export const PressableListItemBase = withLinkRouter(PressableListItemBaseInner)
PressableListItemBase.__UDS_COMPONENT_TYPE__ = 'ListItem'
