import {pluralize} from '@crumbs/core/text'
import {Stack, useRouter} from 'expo-router'
import {useEffect, useState} from 'react'
import {View} from 'react-native'

import {ErrorState} from '@/components/error-state'
import {Avatar} from '@/components/ui/avatar'
import {Card, CardRow, CardRowTitle} from '@/components/ui/card'
import {Layout} from '@/components/ui/layout'
import {List} from '@/components/ui/list'
import {PressableRow} from '@/components/ui/pressable-row'
import {Text} from '@/components/ui/typography'
import {useBusyAction} from '@/hooks/use-busy-action'
import {useFriendSearch} from '@/hooks/use-friend-search'
import {infiniteScroll} from '@/lib/scroll'
import {atoms as a, useTheme} from '@/sprinkles'
import {useOpenConversation} from '@/stores/dms'
import {
  useFriends,
  useFriendsLoading,
  useFriendsLoadingMore,
  useLoadFriends,
  useLoadMoreFriends,
  type PublicProfile,
} from '@/stores/friends'

export default function NewMessageScreen() {
  const router = useRouter()
  const [query, setQuery] = useState('')
  const friends = useFriends()
  const friendsLoading = useFriendsLoading()
  const friendsLoadingMore = useFriendsLoadingMore()
  const loadFriends = useLoadFriends()
  const loadMoreFriends = useLoadMoreFriends()
  const search = useFriendSearch(query)
  const openConversation = useOpenConversation()
  const {busy: pendingId, run} = useBusyAction({haptic: false})

  useEffect(() => {
    void loadFriends()
  }, [loadFriends])

  const searching = search.results !== null || search.loading
  const shown = search.results ?? friends

  const handleSelect = (friendId: string) =>
    run(friendId, async (id) => {
      const conversationId = await openConversation(id)
      // replace so back returns to the inbox, not this picker
      router.replace(`/dms/${conversationId}`)
    })

  return (
    <>
      <Stack.Screen
        options={{
          title: 'New message',
          headerSearchBarOptions: {
            placeholder: 'Search friends',
            onChangeText: ({nativeEvent}) =>
              setQuery(nativeEvent.text),
          },
        }}
      />
      <Layout.ModalContent
        {...(searching ? {} : infiniteScroll(loadMoreFriends))}
      >
        <Card>
          <List
            items={shown}
            loading={searching ? search.loading : friendsLoading}
            loadingMore={searching ? false : friendsLoadingMore}
            emptyMessage={
              searching ? 'No matching friends' : 'No friends yet'
            }
            renderItem={(friend) => (
              <FriendRow
                friend={friend}
                pending={pendingId === friend.id}
                disabled={pendingId !== null}
                onPress={() => void handleSelect(friend.id)}
              />
            )}
          />
        </Card>
        {search.error != null && (
          <ErrorState message={search.error} />
        )}
      </Layout.ModalContent>
    </>
  )
}

const FriendRow = ({
  friend,
  pending,
  disabled,
  onPress,
}: {
  friend: PublicProfile
  pending: boolean
  disabled: boolean
  onPress: () => void
}) => {
  const t = useTheme()
  return (
    <PressableRow
      accessibilityLabel={`Message @${friend.handle}`}
      pending={pending}
      disabled={disabled}
      onPress={onPress}
    >
      <CardRow>
        <View style={[a.flex_row, a.align_center, a.gap_sm]}>
          <Avatar
            handle={friend.handle}
            uri={friend.avatarUrl}
            size={36}
          />
          <CardRowTitle>@{friend.handle}</CardRowTitle>
        </View>
        <Text style={t.atoms.text_contrast_medium}>
          {pluralize(friend.friendCount, 'friend')}
        </Text>
      </CardRow>
    </PressableRow>
  )
}
