import React from 'react'
import PropTypes from 'prop-types'
import { Pressable, Text, Platform } from 'react-native'

import { applyTextStyles } from '../../ThemeProvider/utils/styles'
import { useThemeTokensCallback } from '../../ThemeProvider/useThemeTokens'
import { selectSystemProps } from '../../utils/props/selectSystemProps'
import { a11yProps } from '../../utils/props/a11yProps'
import { pressProps } from '../../utils/props/pressProps'
import { viewProps } from '../../utils/props/viewProps'
import { textProps } from '../../utils/props/textProps'
import { getTokensPropType } from '../../utils/props/tokens'
import { variantProp } from '../../utils/props/variantProp'
import { resolvePressableState } from '../../utils/pressability'

const [selectPressProps, pressPropTypes] = selectSystemProps([a11yProps, pressProps, viewProps])
const [selectTextProps, textPropTypes] = selectSystemProps([textProps])

const selectContainerStyles = ({
  paddingLeft,
  paddingRight,
  paddingTop,
  paddingBottom = 0,
  borderBottomColor,
  borderBottomWidth = 0,
  borderBottomStyle,
  flex,
  alignItems,
  justifyContent
}) => ({
  paddingLeft,
  paddingRight,
  paddingTop,
  paddingBottom: paddingBottom - borderBottomWidth,
  borderBottomColor,
  borderBottomWidth,
  borderBottomStyle,
  flex,
  alignItems,
  justifyContent,
  ...Platform.select({
    // Removes the default browser :focus outline
    web: { outline: 'none' }
  })
})

const selectTextStyles = ({
  fontSize,
  fontScaleCap,
  lineHeight,
  letterSpacing,
  fontWeight,
  fontName,
  color
}) =>
  applyTextStyles({
    fontSize,
    fontScaleCap,
    lineHeight,
    letterSpacing,
    fontWeight,
    fontName,
    color
  })

export const CarouselTabsPanelItem = React.forwardRef(
  ({ title, selected, inactive, variant, tokens, accessibilityRole = 'tab', ...rest }, ref) => {
    // Workaround for React Native Web https://github.com/necolas/react-native-web/issues/2357
    // Don't allow disabled to be set while focus is true else focus state gets locked `true`
    // (must refocus _after_ calling `goTo`, else focus target content is not up to date)
    const [isFocused, setIsFocused] = React.useState(false)
    const disabled = (inactive || selected) && !isFocused

    const getTokens = useThemeTokensCallback('CarouselTabsPanelItem', tokens, variant)
    const resolveTokens = (pressState) => getTokens(resolvePressableState(pressState, { selected }))

    const getContainerStyle = (pressState) => selectContainerStyles(resolveTokens(pressState))

    const getTextStyle = (pressState) => selectTextStyles(resolveTokens(pressState))

    const { onPress, ...selectedPressProps } = selectPressProps(rest)
    const handleKeyDown = (event) => {
      // Allow using the spacebar for navigation
      if (event?.key === ' ') onPress(event)
    }

    return (
      <Pressable
        onPress={onPress}
        style={getContainerStyle}
        accessibilityRole={accessibilityRole}
        ref={ref}
        onKeyDown={handleKeyDown}
        onFocus={() => setIsFocused(true)}
        onBlur={() => setIsFocused(false)}
        disabled={disabled}
        {...selectedPressProps}
      >
        {(pressState) => (
          <Text style={getTextStyle(pressState)} {...selectTextProps(rest)}>
            {title}
          </Text>
        )}
      </Pressable>
    )
  }
)
CarouselTabsPanelItem.displayName = 'CarouselTabsPanelItem'
CarouselTabsPanelItem.propTypes = {
  ...pressPropTypes,
  ...textPropTypes,
  title: PropTypes.string.isRequired,
  selected: PropTypes.bool,
  tokens: getTokensPropType('CarouselTabsPanelItem'),
  variant: variantProp.propType
}
