import { Feather } from '@expo/vector-icons'
import { FlashList } from '@shopify/flash-list'
import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query'
import { type ErrorBoundaryProps, useRouter } from 'expo-router'
import { useMemo, useState } from 'react'
import { ActivityIndicator } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
import { ErrorState } from 'src/components/common/ErrorState'
import type { IconName } from 'src/components/menu'
import { useScreenMenu, useSearchQuery } from 'src/components/menu'
import { ICON } from 'src/lib/icons'
import { adminQueries } from 'src/lib/queries/admin'
import { useActiveProfile } from 'src/state/AuthProvider'
import { enforceLen, prettyCount, timeAgo } from 'src/utils'
import { Separator, Text, useTheme, View, XStack, YStack } from 'tamagui'

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

const keyExtractor = (_: any, index: any) => `instance-${_.id}-${index}`

const SORT_OPTIONS = [
  { value: 'id', label: 'Newest', icon: 'hash' },
  { value: 'status_count', label: 'By posts', icon: 'image' },
  { value: 'user_count', label: 'By users', icon: 'users' },
  { value: 'domain', label: 'By domain', icon: 'globe' },
] as const satisfies ReadonlyArray<{
  value: string
  label: string
  icon: IconName
}>

export default function Page() {
  const router = useRouter()
  const { profile } = useActiveProfile()
  const is_admin = !!profile?.is_admin
  const [sort, _setSort] = useState('desc')
  const [sortBy, setSortBy] = useState<string>('id')
  const [query, setQuery] = useSearchQuery()
  const queryClient = useQueryClient()
  const theme = useTheme()
  const muted = theme.colorTertiary.val

  const handleSortChange = (next: string) => {
    setSortBy(next)
    queryClient.invalidateQueries({
      queryKey: adminQueries.instances(sort, sortBy).queryKey,
    })
  }

  useScreenMenu({
    title: 'Admin · Instances',
    intents: [
      {
        kind: 'search',
        placeholder: 'Filter instances',
        value: query,
        onChangeText: setQuery,
      },
      {
        kind: 'menu',
        accessibilityLabel: 'Sort instances',
        items: SORT_OPTIONS.map((opt) => ({
          id: `sort-${opt.value}`,
          label: opt.label,
          icon: opt.icon,
          toggled: sortBy === opt.value,
          onPress: () => handleSortChange(opt.value),
        })),
      },
    ],
  })

  if (!is_admin) {
    router.back()
  }

  const RenderItem = ({ item }: { item: any }) => {
    return (
      <View px="$5" py="$3" bg="$background">
        <XStack justifyContent="space-between" alignItems="center">
          <YStack>
            <Text fontSize="$6">{enforceLen(item.domain, 30, true, 'middle')}</Text>
            <XStack gap="$3" justifyContent="flex-start" alignItems="center">
              {item.software ? <Text color="$gray9">{item.software}</Text> : null}
            </XStack>
          </YStack>

          <XStack gap="$3">
            {item?.user_count ? (
              <YStack w={50} justifyContent="center" alignItems="center" gap={3}>
                <Text
                  fontSize="$3"
                  fontWeight="bold"
                  color="$gray9"
                  allowFontScaling={false}
                >
                  {prettyCount(item?.user_count)}
                </Text>
                <Feather name="user" size={ICON.xs} color={muted} />
              </YStack>
            ) : null}
            {item?.last_crawled_at ? (
              <YStack w={50} justifyContent="center" alignItems="center" gap={3}>
                <Text
                  fontSize="$3"
                  fontWeight="bold"
                  color="$gray9"
                  allowFontScaling={false}
                >
                  {timeAgo(item?.last_crawled_at)}
                </Text>
                <Feather name="clock" size={ICON.xs} color={muted} />
              </YStack>
            ) : null}

            {/* { item?.status_count ? 
                        <YStack w={50} justifyContent="center" alignItems="center" gap={3}>
                            <Text fontSize="$3" fontWeight="bold" color="$gray9" allowFontScaling={false}>{ prettyCount(item?.status_count) }</Text>
                            <Feather name="image" size={ICON.xs} color={muted} />
                        </YStack> 
                        : null } */}
          </XStack>
        </XStack>
      </View>
    )
  }

  const { data, error, fetchNextPage, hasNextPage, isFetching, isFetchingNextPage } =
    useInfiniteQuery(adminQueries.instances(sort, sortBy))

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

  if (isFetching && !isFetchingNextPage) {
    return (
      <View p="$3">
        <ActivityIndicator />
      </View>
    )
  }

  if (error) {
    return (
      <View>
        <Text>{error.message}</Text>
      </View>
    )
  }

  return (
    <SafeAreaView style={{ flex: 1 }} edges={['top', 'bottom']}>
      <FlashList
        keyExtractor={keyExtractor}
        data={flattenedData}
        renderItem={RenderItem}
        ItemSeparatorComponent={Separator}
        onEndReached={() => {
          if (hasNextPage && !isFetchingNextPage) fetchNextPage()
        }}
        ListFooterComponent={() =>
          isFetchingNextPage ? (
            <View p="$3">
              <ActivityIndicator />
            </View>
          ) : null
        }
        onEndReachedThreshold={0.5}
      />
    </SafeAreaView>
  )
}
