import Feather from '@expo/vector-icons/Feather'
import { FlashList } from '@shopify/flash-list'
import { useQuery } from '@tanstack/react-query'
import { type ErrorBoundaryProps, Link, router, useLocalSearchParams } from 'expo-router'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Keyboard, Pressable } from 'react-native'
import { SafeAreaView } from 'react-native-safe-area-context'
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 UserAvatar from 'src/components/common/UserAvatar'
import EventDetailView from 'src/components/event/EventDetailView'
import { useScreenMenu, useSearchQuery } from 'src/components/menu'
import { useUrlPastePreview } from 'src/hooks/useUrlPastePreview'
import { ICON } from 'src/lib/icons'
import { searchQueries } from 'src/lib/queries/search'
import { getDomain, getReplyCount, prettyCount } from 'src/utils'
import {
  ScrollView,
  Separator,
  Spinner,
  Tabs,
  Text,
  useTheme,
  View,
  XStack,
  YStack,
} from 'tamagui'
import { formatTimestampMonthYear } from '../../../utils'

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

const AccountResultsTab = ({ accounts, isFetching, query }: any) => {
  const RenderAccountItem = useCallback(
    ({ item }: any) => (
      <View p="$3" bg="$background">
        <Link href={`/profile/${item.id}`} asChild>
          <Pressable>
            <XStack alignItems="center" gap="$3">
              <UserAvatar url={item.avatar} size="md" />
              <YStack flexGrow={1} gap={4} w="50%">
                <XStack alignItems="center" gap="$2" flexWrap="wrap">
                  <Text fontSize="$6" fontWeight="bold" color="$color">
                    {item.username}
                  </Text>

                  {!item.local ? (
                    <View bg="$gray3" px={5} py={4} borderRadius={5}>
                      <Text fontSize="$2" fontWeight="bold" color="$colorTertiary">
                        {getDomain(item.url)}
                      </Text>
                    </View>
                  ) : null}
                </XStack>
                <XStack gap="$2" alignItems="center">
                  <Text color="$colorSecondary" fontSize="$2">
                    {prettyCount(item.followers_count)} Followers
                  </Text>
                  <Text color="$colorTertiary">·</Text>
                  <Text color="$colorSecondary" fontSize="$2">
                    {item.local ? 'Joined' : 'First seen'}{' '}
                    {formatTimestampMonthYear(item.created_at)}
                  </Text>
                </XStack>
              </YStack>
            </XStack>
          </Pressable>
        </Link>
      </View>
    ),
    []
  )

  return (
    <View flex={1}>
      <FlashList
        data={accounts}
        renderItem={RenderAccountItem}
        ItemSeparatorComponent={() => <Separator borderColor="$borderColor" />}
        onScrollBeginDrag={() => Keyboard.dismiss()}
        ListEmptyComponent={
          query?.length && !isFetching ? (
            <EmptyState icon="alert-circle" title="No accounts found" />
          ) : null
        }
        ListFooterComponent={<ListFooter loading={isFetching} />}
        contentContainerStyle={{ paddingBottom: 200 }}
      />
    </View>
  )
}

const HashtagResultsTab = ({ hashtags, isFetching, query }: any) => {
  const theme = useTheme()

  const RenderHashtagItem = useCallback(
    ({ item }: any) => (
      <Link href={`/hashtag/${item.name}`} asChild>
        <View px="$4" py="$3" bg="$background">
          <XStack alignItems="center" gap="$4">
            <View
              w={30}
              h={30}
              borderRadius={50}
              bg="$backgroundTertiary"
              justifyContent="center"
              alignItems="center"
            >
              <Feather name="hash" size={ICON.md} color={theme.colorTertiary.val} />
            </View>
            <XStack
              flexGrow={1}
              gap={4}
              flexWrap="wrap"
              justifyContent="space-between"
              alignItems="center"
            >
              <Text
                fontSize="$6"
                w="70%"
                fontWeight="bold"
                flexWrap="wrap"
                color="$color"
              >
                {item.name}
              </Text>
              <XStack>
                <Text color="$colorTertiary" fontSize="$3">
                  {prettyCount(item.count)} posts
                </Text>
              </XStack>
            </XStack>
          </XStack>
        </View>
      </Link>
    ),
    []
  )

  return (
    <View flex={1}>
      <FlashList
        data={hashtags}
        renderItem={RenderHashtagItem}
        ItemSeparatorComponent={() => <Separator borderColor="$borderColor" />}
        onScrollBeginDrag={() => Keyboard.dismiss()}
        ListEmptyComponent={
          query?.length && !isFetching ? (
            <EmptyState icon="alert-circle" title="No hashtags found" />
          ) : null
        }
        ListFooterComponent={<ListFooter loading={isFetching} />}
        contentContainerStyle={{ paddingBottom: 200 }}
      />
    </View>
  )
}

const PostResultsTab = ({ posts, isFetching, query }: any) => {
  const RenderPostItem = useCallback(
    ({ item }: any) => (
      <View p="$3" bg="$background">
        <Link href={`/post/${item.id}`} asChild>
          <Pressable>
            <XStack alignItems="center" gap="$3">
              <UserAvatar url={item.account.avatar} size="md" />
              <YStack flexGrow={1} gap={4}>
                <XStack alignItems="center" flexWrap="wrap" overflow="hidden">
                  <Text fontSize="$6" fontWeight="bold" color="$color">
                    {item.account.username}
                  </Text>

                  {!item.account.local ? (
                    <Text fontSize="$6" color="$colorTertiary">
                      @{getDomain(item.account.url)}
                    </Text>
                  ) : null}
                </XStack>
                <XStack gap="$2" alignItems="center">
                  <Text color="$color" fontSize="$2">
                    Post
                  </Text>
                  <Text color="$colorTertiary">·</Text>
                  <Text color="$colorSecondary" fontSize="$2">
                    {prettyCount(item.favourites_count)} likes
                  </Text>
                  <Text color="$colorTertiary">·</Text>
                  <Text color="$colorSecondary" fontSize="$2">
                    {prettyCount(getReplyCount(item))} comments
                  </Text>
                  <Text color="$colorTertiary">·</Text>
                  <Text color="$colorSecondary" fontSize="$2">
                    Created {formatTimestampMonthYear(item.created_at)}
                  </Text>
                </XStack>
              </YStack>
            </XStack>
          </Pressable>
        </Link>
      </View>
    ),
    []
  )

  return (
    <View flex={1}>
      <FlashList
        data={posts}
        renderItem={RenderPostItem}
        ItemSeparatorComponent={() => <Separator borderColor="$borderColor" />}
        onScrollBeginDrag={() => Keyboard.dismiss()}
        ListEmptyComponent={
          query?.length && !isFetching ? (
            <EmptyState icon="alert-circle" title="No posts found" />
          ) : null
        }
        ListFooterComponent={<ListFooter loading={isFetching} />}
        contentContainerStyle={{ paddingBottom: 200 }}
      />
    </View>
  )
}

export default function SearchScreen() {
  const { initialQuery } = useLocalSearchParams<{ initialQuery?: string }>()
  const [query, setQuery] = useSearchQuery(initialQuery || '')
  const [activeTab, setActiveTab] = useState('accounts')
  const debounceTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)

  useScreenMenu({
    intents: [
      {
        kind: 'search',
        placeholder: 'Search by hashtag, profile or url',
        value: query,
        onChangeText: setQuery,
        mode: 'inline',
        keepVisibleOnKeyboard: true,
      },
    ],
  })

  const { data, isLoading, isFetching } = useQuery(searchQueries.results(query))

  const { data: urlPreview, isFetching: isResolvingUrl } = useUrlPastePreview(query)

  // If the pasted URL resolved to a local Status, navigate straight to the
  // permalink so the user gets full interaction. Remote events fall through
  // to a read-only panel rendered inline below the input.
  useEffect(() => {
    if (urlPreview?.kind === 'local') {
      router.replace(`/post/${urlPreview.status.id}`)
    }
  }, [urlPreview])

  const accounts = (data as any)?.filter((item: any) => item._type === 'account') || []
  const hashtags = (data as any)?.filter((item: any) => item._type === 'hashtag') || []
  const posts = (data as any)?.filter((item: any) => item._type === 'status') || []

  useEffect(() => {
    if (debounceTimeoutRef.current) {
      clearTimeout(debounceTimeoutRef.current)
    }

    debounceTimeoutRef.current = setTimeout(() => {
      const isHashtagQuery = query.trim().startsWith('#') && query.trim().length > 1
      if (isHashtagQuery) {
        setActiveTab('hashtags')
      }
    }, 500)

    return () => {
      if (debounceTimeoutRef.current) {
        clearTimeout(debounceTimeoutRef.current)
      }
    }
  }, [query])

  useEffect(() => {
    if (initialQuery?.trim().startsWith('#') && initialQuery?.trim().length > 1) {
      setActiveTab('hashtags')
    }
  }, [initialQuery])

  if (isLoading && !isFetching) return <LoadingView />

  return (
    <SafeAreaView edges={['top', 'bottom']} style={{ flex: 1 }}>
      <View flex={1}>
        {urlPreview?.kind === 'remote-event' ? (
          <ScrollView flex={1}>
            <EventDetailView post={urlPreview.status} readOnly />
          </ScrollView>
        ) : urlPreview?.kind === 'loading' || isResolvingUrl ? (
          <View flex={1} justifyContent="center" alignItems="center">
            <Spinner color="$color" />
          </View>
        ) : urlPreview?.kind === 'unsupported' ? (
          <View p="$4">
            <EmptyState
              icon="link"
              title="Can't preview this URL"
              subtitle="We couldn't resolve this link through your server or as a supported fediverse event."
            />
          </View>
        ) : (
          <Tabs
            value={activeTab}
            onValueChange={setActiveTab}
            orientation="horizontal"
            flexDirection="column"
            flex={1}
          >
            <Tabs.List borderBottomWidth={1} borderColor="$borderColor">
              <Tabs.Tab
                flex={1}
                value="accounts"
                borderBottomWidth={2}
                borderColor={activeTab === 'accounts' ? '$color' : 'transparent'}
                bg="transparent"
                py="$3"
              >
                <Text
                  fontWeight="bold"
                  fontSize="$3"
                  color={activeTab === 'accounts' ? '$color' : '$colorTertiary'}
                >
                  Accounts
                </Text>
              </Tabs.Tab>
              <Tabs.Tab
                flex={1}
                value="hashtags"
                borderBottomWidth={2}
                borderColor={activeTab === 'hashtags' ? '$color' : 'transparent'}
                bg="transparent"
                py="$3"
              >
                <Text
                  fontWeight="bold"
                  fontSize="$3"
                  color={activeTab === 'hashtags' ? '$color' : '$colorTertiary'}
                >
                  Hashtags
                </Text>
              </Tabs.Tab>
              <Tabs.Tab
                flex={1}
                value="posts"
                borderBottomWidth={2}
                borderColor={activeTab === 'posts' ? '$color' : 'transparent'}
                bg="transparent"
                py="$3"
              >
                <Text
                  fontWeight="bold"
                  fontSize="$3"
                  color={activeTab === 'posts' ? '$color' : '$colorTertiary'}
                >
                  Posts
                </Text>
              </Tabs.Tab>
            </Tabs.List>

            <Tabs.Content value="accounts" flex={1}>
              <AccountResultsTab
                accounts={accounts}
                isFetching={isFetching}
                query={query}
              />
            </Tabs.Content>
            <Tabs.Content value="hashtags" flex={1}>
              <HashtagResultsTab
                hashtags={hashtags}
                isFetching={isFetching}
                query={query}
              />
            </Tabs.Content>
            <Tabs.Content value="posts" flex={1}>
              <PostResultsTab posts={posts} isFetching={isFetching} query={query} />
            </Tabs.Content>
          </Tabs>
        )}
      </View>
    </SafeAreaView>
  )
}
