import { FlashList } from '@shopify/flash-list'
import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
import { Link, Stack, useLocalSearchParams } from 'expo-router'
import { useMemo } from 'react'
import { Pressable } from 'react-native'
import { EmptyState } from 'src/components/common/EmptyState'
import { ErrorState } from 'src/components/common/ErrorState'
import { ListFooter } from 'src/components/common/ListFooter'
import { LoadingView } from 'src/components/common/LoadingView'
import { UserRow } from 'src/components/common/UserRow'
import { ScreenScrollContainer } from 'src/components/layout'
import { useMenuScroll, useScreenMenu, useSearchQuery } from 'src/components/menu'
import { accountQueries } from 'src/lib/queries/accounts'
import { Separator } from 'tamagui'

type Props = {
  type: 'followers' | 'following'
}

export function AccountListScreen({ type }: Props) {
  const { id } = useLocalSearchParams<{ id: string }>()
  const [query, setQuery] = useSearchQuery()

  const { data: profile } = useQuery(accountQueries.byId(id))
  const profileId = profile?.id

  const {
    data: feed,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isFetching,
    error,
    refetch,
  } = useInfiniteQuery({
    ...(accountQueries[type](profileId as string) as ReturnType<
      typeof accountQueries.followers
    >),
    enabled: !!profile,
  })

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

  const title = type === 'followers' ? 'Followers' : 'Following'

  useScreenMenu({
    title,
    intents: [
      { kind: 'back' },
      {
        kind: 'search',
        placeholder: `Filter ${title.toLowerCase()}`,
        value: query,
        onChangeText: setQuery,
      },
    ],
  })

  const onScroll = useMenuScroll(true)

  if (isFetching && !isFetchingNextPage) return <LoadingView />
  if (error) return <ErrorState onRetry={refetch} />

  return (
    <>
      <Stack.Screen options={{ title, headerBackTitle: 'Back' }} />
      <ScreenScrollContainer variant="flashlist">
        {(scrollProps) => (
          <FlashList
            data={flattenedData}
            renderItem={({ item }) => (
              <Link href={`/profile/${item.id}`} asChild>
                <Pressable>
                  <Link.Trigger>
                    <UserRow account={item} />
                  </Link.Trigger>
                  <Link.Preview style={{ width: 320, height: 420 }} />
                </Pressable>
              </Link>
            )}
            keyExtractor={(item) => item.id.toString()}
            ItemSeparatorComponent={() => <Separator borderColor="$borderColor" />}
            showsVerticalScrollIndicator={false}
            onEndReached={() => {
              if (hasNextPage && !isFetchingNextPage) fetchNextPage()
            }}
            onEndReachedThreshold={0.5}
            ListEmptyComponent={
              <EmptyState icon="alert-circle" title="No results found" />
            }
            onScroll={onScroll}
            ListFooterComponent={<ListFooter loading={isFetchingNextPage} />}
            contentInsetAdjustmentBehavior={scrollProps.contentInsetAdjustmentBehavior}
            contentInset={scrollProps.contentInset}
            scrollIndicatorInsets={scrollProps.scrollIndicatorInsets}
            contentContainerStyle={{
              ...scrollProps.contentContainerStyle,
              flexGrow: 1,
            }}
          />
        )}
      </ScreenScrollContainer>
    </>
  )
}
