import {useLocalSearchParams} from 'expo-router'
import {useEffect, useState} from 'react'

import {ModalListScreen} from '@/components/modal-list-screen'
import {CardRow, CardRowTitle} from '@/components/ui/card'
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 {useTheme} from '@/sprinkles'
import {
  useFriends,
  useFriendsLoading,
  useFriendsLoadingMore,
  useLoadFriends,
  useLoadMoreFriends,
} from '@/stores/friends'
import {useInviteToTrail, useTrail} from '@/stores/trails'

export default function InviteToTrailScreen() {
  const {trailId} = useLocalSearchParams<{trailId: string}>()
  const t = useTheme()
  const trail = useTrail(trailId)
  const friends = useFriends()
  const loading = useFriendsLoading()
  const loadingMore = useFriendsLoadingMore()
  const refreshFriends = useLoadFriends()
  const loadMore = useLoadMoreFriends()
  const invite = useInviteToTrail()
  const {
    busy: pendingId,
    error,
    run,
  } = useBusyAction({inlineError: true})
  const [invitedIds, setInvitedIds] = useState<string[]>([])

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

  const memberIds = new Set([
    ...(trail ? [trail.authorId] : []),
    ...(trail?.collaborators.map((c) => c.id) ?? []),
  ])
  const invitable = friends.filter((f) => !memberIds.has(f.id))

  const handleInvite = (friendId: string) =>
    run(friendId, async (id) => {
      await invite(trailId, id)
      setInvitedIds((ids) => [...ids, id])
    })

  return (
    <ModalListScreen
      title="Invite to trail"
      onEndReached={() => void loadMore()}
      error={error}
    >
      <List
        items={invitable}
        loading={loading}
        loadingMore={loadingMore}
        emptyMessage="No friends to invite"
        renderItem={(friend) => {
          const invited = invitedIds.includes(friend.id)
          return (
            <PressableRow
              accessibilityLabel={`Invite @${friend.handle}`}
              disabled={pendingId !== null || invited}
              pending={pendingId === friend.id || invited}
              onPress={() => void handleInvite(friend.id)}
            >
              <CardRow
                trailing={
                  <Text style={t.atoms.text_contrast_medium}>
                    {invited ? 'Invited' : 'Invite'}
                  </Text>
                }
              >
                <CardRowTitle>@{friend.handle}</CardRowTitle>
              </CardRow>
            </PressableRow>
          )
        }}
      />
    </ModalListScreen>
  )
}
