import MaskedView from '@react-native-masked-view/masked-view'
import { X, RefreshCw, SendHorizontal } from '@tamagui/lucide-icons'
import { useRef, useState, useEffect, useCallback, memo } from 'react'
import { NativeSyntheticEvent, NativeScrollEvent } from 'react-native'
import { XStack, YStack, ZStack, Text, Button, ScrollView, Input } from 'tamagui'
import { LinearGradient } from 'tamagui/linear-gradient'

const buttonProps = {
  w: '$4',
  h: '$4',
  br: '$10',
  chromeless: true,
  backgroundColor: 'rgba(0, 0, 0, 0.2)',
  pressStyle: {
    backgroundColor: 'rgba(0, 0, 0, 0.3)',
    borderColor: 'transparent',
  },
} as const

export type Comment = {
  id?: string
  commenter: string
  text: string
  time: string
}

export type CameraViewProps = {
  children?: React.ReactNode
  onCloseCamera: () => void
  onFlipCamera: () => void
  commentsQueue: Comment[]
  setCommentsQueue: (comments: Comment[]) => void
}

const TopActionBar = memo(
  ({ onCloseCamera, onFlipCamera }: { onCloseCamera: () => void; onFlipCamera: () => void }) => (
    <XStack
      pt="$10"
      px="$6"
      width="100%"
      justifyContent="space-between"
    >
      <Button
        {...buttonProps}
        icon={X}
        onPress={onCloseCamera}
      />
      <Button
        {...buttonProps}
        icon={RefreshCw}
        onPress={onFlipCamera}
      />
    </XStack>
  )
)

const CommentItem = memo(({ comment }: { comment: Comment }) => (
  <YStack
    br="$4"
    p="$2"
    mb="$1"
    animation="medium"
    backgroundColor="rgba(0, 0, 0, 0.25)"
    enterStyle={{
      opacity: 0,
      y: 20,
    }}
  >
    <XStack gap="$2">
      <Text
        color="rgba(255, 255, 255, 0.7)"
        fontWeight="bold"
      >
        {comment.commenter}
      </Text>
      <Text color="rgba(255, 255, 255, 0.5)">{new Date(comment.time).toLocaleTimeString()}</Text>
    </XStack>
    <Text color="white">{comment.text}</Text>
  </YStack>
))

const CommentsViewport = memo(
  ({
    commentsQueue,
    setCommentsQueue,
  }: {
    commentsQueue: Comment[]
    setCommentsQueue: (comments: Comment[]) => void
  }) => {
    const scrollViewRef = useRef<ScrollView>(null)
    const [autoScroll, setAutoScroll] = useState(true)
    const [displayedComments, setDisplayedComments] = useState<Comment[]>([])

    useEffect(() => {
      if (commentsQueue.length === 0) return

      const displayNewComments = async () => {
        if (commentsQueue.length === 0) return

        const processQueue = async () => {
          for (const comment of commentsQueue) {
            const delay = comment.text.length * 50
            await new Promise((resolve) => setTimeout(resolve, delay))
            setDisplayedComments((prev) => [...prev, comment])
          }
          setCommentsQueue([])
        }

        processQueue()
      }

      displayNewComments()
    }, [commentsQueue, setCommentsQueue])

    const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {
      const { contentOffset, contentSize, layoutMeasurement } = event.nativeEvent
      if (!contentOffset) return

      const distanceFromBottom =
        (contentSize?.height || 0) - (contentOffset.y + layoutMeasurement?.height || 0)
      const isNearBottom = distanceFromBottom < 10

      setAutoScroll(isNearBottom)
    }, [])

    return (
      <ZStack
        flex={1}
        w="100%"
        h="70%"
        position="absolute"
        bottom={0}
      >
        <YStack
          flex={1}
          mb="$5"
          overflow="hidden"
        >
          <MaskedView
            style={{ flex: 1 }}
            maskElement={
              <LinearGradient
                height="100%"
                colors={['transparent', 'white', 'white']}
                start={[0, 0]}
                end={[0, 1]}
                locations={[0, 0.3, 1]}
              />
            }
          >
            <MaskedView
              style={{ flex: 1 }}
              maskElement={
                <LinearGradient
                  height="100%"
                  colors={['white', 'white', autoScroll ? 'white' : 'transparent']}
                  start={[0, 0]}
                  end={[0, 1]}
                  locations={[0, 0.99, 1]}
                />
              }
            >
              <ScrollView
                ref={scrollViewRef}
                onScroll={handleScroll}
                scrollEventThrottle={16}
                onContentSizeChange={() => {
                  if (autoScroll) {
                    scrollViewRef.current?.scrollToEnd({ animated: false })
                  }
                }}
                bounces={false}
                showsVerticalScrollIndicator={false}
                scrollEnabled
                nestedScrollEnabled
                contentContainerStyle={{
                  flexGrow: 1,
                  justifyContent: 'flex-start',
                  paddingHorizontal: 16,
                  paddingBottom: 16,
                }}
                automaticallyAdjustKeyboardInsets
              >
                <YStack
                  flex={1}
                  justifyContent="flex-end"
                >
                  {displayedComments.map((comment) => (
                    <CommentItem comment={comment} />
                  ))}
                </YStack>
              </ScrollView>
            </MaskedView>
          </MaskedView>

          <XStack
            p="$2"
            px="$3"
            bc="rgba(0, 0, 0, 0.3)"
            br="$10"
            mx="$5"
            mt="$2"
          >
            <Input
              f={1}
              placeholder="Comment"
              placeholderTextColor="rgba(255, 255, 255, 0.5)"
              editable={false}
              bc="transparent"
              bw={0}
              color="white"
            />
            <Button
              chromeless
              disabled
              opacity={0.5}
            >
              <SendHorizontal color="white" />
            </Button>
          </XStack>
        </YStack>
      </ZStack>
    )
  }
)

export const CameraView = memo(({ children, ...props }: CameraViewProps) => (
  <ZStack f={1}>
    {children}
    <YStack f={1}>
      <TopActionBar
        onCloseCamera={props.onCloseCamera}
        onFlipCamera={props.onFlipCamera}
      />
      <CommentsViewport {...props} />
    </YStack>
  </ZStack>
))
