import React from 'react'
import { Text } from 'react-native'

import PropTypes from 'prop-types'

import { ButtonBase } from '../Button/ButtonBase'
import { IconText } from '../Icon/IconText'
import { useThemeTokensCallback } from '../ThemeProvider/useThemeTokens'
import { useViewport } from '../ViewportProvider/useViewport'
import { copyPropTypes } from '../utils/props/copyPropTypes'
import { hrefAttrsProp } from '../utils/props/hrefAttrsProp'
import { linkProps } from '../utils/props/linkProps'
import { selectTokens } from '../utils/props/tokens'
import { withLinkRouter } from '../utils/withLinkRouter'

import { dictionary } from './dictionary'
import { useCopy } from '../utils/useCopy'

// We need to drop the icon here since it gets rendered via children and not
// `ButtonBase` in order to tap into the state of the button; `displayLabel` flag
// is also not needed
const selectButtonTokens = ({ icon: _, displayLabel: __, ...rest }) => selectTokens('Button', rest)
const selectIconTokens = ({ color, iconSize, iconDisplace }, direction) => {
  return {
    color,
    size: iconSize,
    translateX: iconDisplace * (direction === 'previous' ? -1 : 1)
  }
}

const directionToSide = {
  previous: 'left',
  next: 'right'
}

const SideButtonInner = React.forwardRef(
  ({ direction = 'previous', onPress, href, copy, variant, tokens, ...props }, ref) => {
    const viewport = useViewport()
    const buttonVariant = { direction, viewport, ...variant }
    const getTokens = useThemeTokensCallback('PaginationSideButton', tokens, buttonVariant)

    const getCopy = useCopy({ dictionary, copy })

    const { icon, displayLabel } = getTokens(tokens, buttonVariant)

    const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
    const getIconTokens = (buttonState) => selectIconTokens(getTokens(buttonState), direction)

    const label = direction === 'previous' ? getCopy('previousText') : getCopy('nextText')

    const accessibilityLabel =
      direction === 'previous' ? getCopy('previousLabel') : getCopy('nextLabel')
    const accessibilityRole = href !== undefined ? 'link' : 'button'

    const { hrefAttrs, rest } = hrefAttrsProp.bundle(props)
    const buttonProps = {
      accessibilityRole,
      accessibilityLabel,
      onPress,
      href,
      hrefAttrs,
      ...rest
    }

    return (
      <ButtonBase ref={ref} {...buttonProps} tokens={getButtonTokens}>
        {({ textStyles, ...buttonState }) => {
          const iconProps = { tokens: getIconTokens(buttonState) }
          return (
            <IconText
              icon={icon}
              space={1}
              iconPosition={directionToSide[direction]}
              iconProps={iconProps}
            >
              {displayLabel && <Text style={textStyles}>{label}</Text>}
            </IconText>
          )
        }}
      </ButtonBase>
    )
  }
)
SideButtonInner.displayName = 'SideButton'

SideButtonInner.propTypes = {
  direction: PropTypes.oneOf(['previous', 'next']),
  copy: copyPropTypes,
  ...linkProps.types
}

export const SideButton = withLinkRouter(SideButtonInner)
