import React from 'react'
import PropTypes from 'prop-types'
import { View } from 'react-native'
import { resolvePressableState } from '../utils/pressability'
import { useAnimatedValue } from '../utils/animation/useAnimatedValue'
import { Progress } from '../Progress/Progress'
import { ProgressBar } from '../Progress/ProgressBar'

const MAX_PERCENTAGE = 100
const BORDER_RADIUS_DIVISOR = 2

const staticProgressTokens = {
  borderWidth: 0,
  borderColor: 'transparent'
}

const staticProgressBarTokens = {
  gradient: null,
  outlineWidth: 0
}

const selectProgressTokens = ({ progressTrackHeight, progressBarHeight, progressTrackColor }) => ({
  height: progressTrackHeight,
  barHeight: progressBarHeight,
  backgroundColor: progressTrackColor,
  borderRadius: progressTrackHeight / BORDER_RADIUS_DIVISOR
})

const selectBarTokens = ({ progressBarColor, progressBarHeight }) => ({
  backgroundColor: progressBarColor,
  borderRadius: progressBarHeight / BORDER_RADIUS_DIVISOR
})

export const ScrollProgress = React.forwardRef(
  ({ pressableState, getTokens, thumbWrapperStyle, getCopy }, ref) => {
    const state = resolvePressableState(pressableState)
    const themeTokens = getTokens(state)
    const animatedBarHeight = useAnimatedValue(themeTokens.progressBarHeight)
    const animatedTokens = { ...themeTokens, progressBarHeight: animatedBarHeight }

    return (
      <Progress tokens={{ ...staticProgressTokens, ...selectProgressTokens(animatedTokens) }}>
        <View ref={ref} style={thumbWrapperStyle}>
          <ProgressBar
            percentage={MAX_PERCENTAGE}
            tokens={{ ...staticProgressBarTokens, ...selectBarTokens(animatedTokens) }}
            accessibilityLabel={getCopy('progressBarLabel')}
          />
        </View>
      </Progress>
    )
  }
)

ScrollProgress.displayName = 'ScrollProgress'

ScrollProgress.propTypes = {
  /**
   * State object from Pressable's render callback containing hovered, pressed, and focused states
   */
  pressableState: PropTypes.object.isRequired,
  /**
   * Theme token resolver callback from useThemeTokensCallback that accepts appearance state
   */
  getTokens: PropTypes.func.isRequired,
  /**
   * Style array for the thumb wrapper containing static and dynamic position styles
   */
  thumbWrapperStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
  /**
   * Copy resolver function from useCopy for retrieving localized strings
   */
  getCopy: PropTypes.func.isRequired
}
