import { Feather } from '@expo/vector-icons'
import { FlashList } from '@shopify/flash-list'
import { useInfiniteQuery } from '@tanstack/react-query'
import type { ErrorBoundaryProps } from 'expo-router'
import { useLocalSearchParams, useRouter } from 'expo-router'
import type React from 'react'
import { useMemo } from 'react'
import { ActivityIndicator, Pressable } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import EmojiText from 'src/components/common/EmojiText'
import { ErrorState } from 'src/components/common/ErrorState'
import UserAvatar from 'src/components/common/UserAvatar'
import { useScreenMenu, useSearchQuery } from 'src/components/menu'
import { useRequirePixelfed } from 'src/hooks/useRequirePixelfed'
import type { CustomEmoji } from 'src/lib/api-types'
import { ICON } from 'src/lib/icons'
import { storyQueries } from 'src/lib/queries/stories'
import { timeAgo } from 'src/utils'
import { Button, Separator, Text, useTheme, XStack, YStack } from 'tamagui'

interface Viewer {
  id: string
  username: string
  name?: string
  display_name?: string
  acct: string
  avatar: string
  viewed_at: string
  emojis?: Array<CustomEmoji>
}

export function ErrorBoundary({ error, retry }: ErrorBoundaryProps) {
  return <ErrorState message={error.message} onRetry={retry} />
}

export default function Page() {
  // Mastodon Pass Phase 4 §5.3 — Stories are Pixelfed-only.
  useRequirePixelfed()
  const { id } = useLocalSearchParams()
  const router = useRouter()
  const theme = useTheme()
  const [query, setQuery] = useSearchQuery()
  useScreenMenu({
    title: 'Story Viewers',
    intents: [
      {
        kind: 'search',
        placeholder: 'Filter viewers',
        value: query,
        onChangeText: setQuery,
      },
    ],
  })

  const onBack = () => {
    router.back()
  }

  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isLoading,
    error,
    refetch,
  } = useInfiniteQuery({
    ...storyQueries.viewers(id as string),
    enabled: !!id,
    staleTime: 1000 * 60 * 5,
  })

  const viewers = useMemo(() => {
    const flat = data?.pages?.flatMap((page) => page.data) || []
    const q = query.trim().toLowerCase()
    if (!q) return flat
    return flat.filter((v: Viewer) => {
      const acct = v?.acct?.toLowerCase() ?? ''
      const username = v?.username?.toLowerCase() ?? ''
      const name = v?.display_name?.toLowerCase() ?? ''
      return acct.includes(q) || username.includes(q) || name.includes(q)
    })
  }, [data, query])

  const ViewerItem: React.FC<{
    viewer: Viewer
    theme: any
  }> = ({ viewer, theme }) => {
    const viewedAgo = useMemo(() => {
      return timeAgo(viewer?.viewed_at)
    }, [viewer?.viewed_at])

    const router = useRouter()

    const gotoProfile = () => {
      router.push(`/profile/${viewer?.id}`)
    }

    return (
      <Pressable onPress={gotoProfile}>
        <XStack
          padding={12}
          alignItems="center"
          gap={12}
          backgroundColor={theme.background.val}
        >
          <UserAvatar url={viewer?.avatar} initial={viewer?.username} size="md" />

          <YStack flex={1} gap={5}>
            <EmojiText
              variant="subhead"
              text={viewer?.name || viewer?.username}
              emojis={viewer?.emojis}
              fontWeight="600"
            />
            {viewer?.display_name && (
              <Text color={theme.colorSecondary.val} fontSize={16}>
                @{viewer?.acct}
              </Text>
            )}
            <Text color={theme.colorTertiary.val} fontSize={12}>
              Viewed {viewedAgo} ago
            </Text>
          </YStack>
        </XStack>
      </Pressable>
    )
  }

  const renderViewer = ({ item }: { item: Viewer }) => (
    <ViewerItem viewer={item} theme={theme} />
  )

  const renderFooter = () => {
    if (isFetchingNextPage) {
      return (
        <YStack padding={20} alignItems="center">
          <ActivityIndicator size="small" color={theme.colorSecondary.val} />
          <Text color={theme.colorSecondary.val} fontSize={14} marginTop={8}>
            Loading more viewers...
          </Text>
        </YStack>
      )
    }

    if (!hasNextPage && viewers.length > 0) {
      return <YStack height={20} />
    }

    return null
  }

  const handleLoadMore = () => {
    if (hasNextPage && !isFetchingNextPage) {
      fetchNextPage()
    }
  }

  if (isLoading) {
    return (
      <SafeAreaView
        style={{ flex: 1, backgroundColor: theme.background.val }}
        edges={['top', 'bottom']}
      >
        <YStack flex={1} alignItems="center" justifyContent="center" gap={16}>
          <ActivityIndicator size="large" color={theme.colorSecondary.val} />
          <Text color={theme.colorSecondary.val}>Loading viewers...</Text>
        </YStack>
      </SafeAreaView>
    )
  }

  if (error) {
    return (
      <SafeAreaView
        style={{ flex: 1, backgroundColor: theme.background.val }}
        edges={['top', 'bottom']}
      >
        <YStack
          flex={1}
          alignItems="center"
          justifyContent="center"
          gap={16}
          padding={20}
        >
          <Feather
            name="alert-circle"
            size={ICON.empty}
            color={theme.colorSecondary.val}
          />
          <Text color={theme.colorSecondary.val} textAlign="center">
            Failed to load story viewers
          </Text>
          <Text color={theme.colorTertiary.val} textAlign="center" fontSize={14}>
            Please check your connection and try again
          </Text>
          <XStack gap={12}>
            <Button
              size="$3"
              onPress={() => refetch()}
              backgroundColor={theme.backgroundTertiary.val}
            >
              <Text color={theme.color.val}>Retry</Text>
            </Button>
            <Button
              size="$3"
              onPress={onBack}
              backgroundColor={theme.backgroundTertiary.val}
            >
              <Text color={theme.color.val}>Go Back</Text>
            </Button>
          </XStack>
        </YStack>
      </SafeAreaView>
    )
  }

  return (
    <SafeAreaView
      style={{ flex: 1, backgroundColor: theme.background.val }}
      edges={['top', 'bottom']}
    >
      {viewers.length === 0 ? (
        <YStack
          flex={1}
          alignItems="center"
          justifyContent="center"
          gap={16}
          padding={20}
        >
          <Feather name="eye-off" size={ICON.empty} color={theme.colorSecondary.val} />
          <Text color={theme.colorSecondary.val} textAlign="center">
            No viewers yet
          </Text>
          <Text color={theme.colorTertiary.val} textAlign="center" fontSize={14}>
            When people view your story, they'll appear here
          </Text>
        </YStack>
      ) : (
        <FlashList
          data={viewers}
          keyExtractor={(item, index) => item?.id + '_index:' + index}
          renderItem={renderViewer}
          onEndReached={handleLoadMore}
          onEndReachedThreshold={0.3}
          ListFooterComponent={renderFooter}
          showsVerticalScrollIndicator={false}
          contentContainerStyle={{ paddingBottom: 20 }}
          ItemSeparatorComponent={() => (
            <Separator borderColor={theme.borderColor.val} marginHorizontal={20} />
          )}
        />
      )}
    </SafeAreaView>
  )
}
