import { LinearGradient } from '@tamagui/linear-gradient'
import { useEffect, useState } from 'react'
import { StyleSheet } from 'react-native'
import Animated, {
  Easing,
  useAnimatedStyle,
  useSharedValue,
  withRepeat,
  withTiming,
} from 'react-native-reanimated'
import { useInflightSnapshot } from 'src/state/InflightProvider'
import { useTheme, View } from 'tamagui'

// 2px-tall indicator that paints at the top edge of a MenuSurfacePill while
// any inflight handle is live. Indeterminate by default (a 40%-width accent
// highlight loops left-to-right); switches to a proportional fill if the
// handle reports `setProgress`.
//
// The component mounts inside the pill's existing rounded clip so the bar
// follows the pill's shape automatically. When `count === 0` we return null
// so the pill renders unchanged in its idle state.

const INDETERMINATE_CYCLE_MS = 1200
const HIGHLIGHT_FRACTION = 0.4

export function InflightBar() {
  const { count, progress } = useInflightSnapshot()
  const active = count > 0
  const theme = useTheme()
  const slide = useSharedValue(0)
  const [width, setWidth] = useState(0)

  const isIndeterminate = active && progress === undefined
  const highlightWidth = Math.max(width * HIGHLIGHT_FRACTION, 32)

  useEffect(() => {
    if (!isIndeterminate) {
      slide.value = 0
      return
    }
    slide.value = 0
    slide.value = withRepeat(
      withTiming(1, { duration: INDETERMINATE_CYCLE_MS, easing: Easing.linear }),
      -1,
      false
    )
    return () => {
      slide.value = 0
    }
  }, [isIndeterminate, slide])

  const animatedStyle = useAnimatedStyle(() => ({
    transform: [{ translateX: -highlightWidth + slide.value * (width + highlightWidth) }],
  }))

  if (!active) return null

  const accent = theme.onSurfaceActive.val as string

  if (progress !== undefined) {
    return (
      <View
        position="absolute"
        top={0}
        left={0}
        right={0}
        height={2}
        zIndex={2}
        pointerEvents="none"
      >
        <View
          position="absolute"
          top={0}
          bottom={0}
          left={0}
          width={`${Math.round(progress * 100)}%`}
          backgroundColor={accent}
        />
      </View>
    )
  }

  return (
    <View
      position="absolute"
      top={0}
      left={0}
      right={0}
      height={2}
      zIndex={2}
      overflow="hidden"
      pointerEvents="none"
      onLayout={(e) => setWidth(e.nativeEvent.layout.width)}
    >
      {width > 0 ? (
        <Animated.View
          style={[
            {
              position: 'absolute',
              top: 0,
              bottom: 0,
              width: highlightWidth,
            },
            animatedStyle,
          ]}
        >
          <LinearGradient
            colors={['transparent', accent, 'transparent']}
            start={[0, 0.5]}
            end={[1, 0.5]}
            style={StyleSheet.absoluteFill}
          />
        </Animated.View>
      ) : null}
    </View>
  )
}
