import { useCallback, useMemo, useRef } from 'react'
import { FlatList } from 'react-native'
import type { ScreenScrollChildProps } from 'src/components/layout'
import CommentItem from 'src/components/post/CommentItem'
import { buildThreadTree, type Comment, flattenWithDepth } from 'src/lib/comments'
import { Text, useTheme, YStack } from 'tamagui'

type Handlers = {
  onReply: (comment: Comment) => void
  onLike: (comment: Comment) => void
  onReport: (postId: string) => void
  onDelete: (id: string) => void
  onShowLikes: (postId: string) => void
  onViewReplies?: (comment: Comment) => void
  gotoProfile: (userId: string) => void
  gotoUsernameProfile: (username: string) => void
  gotoHashtag: (hashtag: string) => void
}

type Props = Handlers & {
  comments: Comment[]
  // Anchor id powers `buildThreadTree` so top-level replies are detected
  // (anything whose `in_reply_to_id === anchorId`). Always required.
  anchorId: string
  user: any
  // Slotted in as the FlatList header so [ancestors + anchor] sit above
  // the descendant rows in a single virtualized scroll surface.
  ListHeaderComponent?: React.ReactElement | null
  // Optional inset-layout props from ScreenScrollContainer. When present,
  // they're merged with the list's own padding so the first row starts
  // below the status bar and the bottom inset still applies.
  scrollProps?: ScreenScrollChildProps
}

// Reserved bottom padding so the last comment doesn't pin to the safe-area
// edge under the tab bar. The composer is no longer mounted on this
// screen — replies push the modal — so there's no keyboard-aware
// adjustment. Constant ~40px is enough to clear the tab bar's shadow on
// both platforms.
const BOTTOM_INSET = 40

export function CommentThreadList({
  comments,
  anchorId,
  user,
  ListHeaderComponent,
  scrollProps,
  ...handlers
}: Props) {
  const theme = useTheme()
  const flatListRef = useRef<FlatList<any>>(null)

  // Single render path: depth-annotated DFS preorder. Stable across
  // re-renders that don't refetch (the React Query reference is stable).
  const rows = useMemo(() => {
    const { roots } = buildThreadTree(comments, anchorId)
    return flattenWithDepth(roots)
  }, [comments, anchorId])

  const renderItem = useCallback(
    ({ item }: { item: { comment: Comment; depth: number } }) => (
      <CommentItem
        item={item.comment}
        depth={item.depth}
        user={user}
        onReply={handlers.onReply}
        onLike={handlers.onLike}
        onReport={handlers.onReport}
        onDelete={handlers.onDelete}
        onShowLikes={handlers.onShowLikes}
        onViewReplies={handlers.onViewReplies}
        gotoProfile={handlers.gotoProfile}
        gotoUsernameProfile={handlers.gotoUsernameProfile}
        gotoHashtag={handlers.gotoHashtag}
      />
    ),
    [user, handlers]
  )

  const contentContainerStyle = scrollProps
    ? {
        flexGrow: 1,
        paddingTop: scrollProps.contentContainerStyle.paddingTop,
        paddingBottom:
          BOTTOM_INSET + (scrollProps.contentContainerStyle.paddingBottom ?? 0),
      }
    : { flexGrow: 1, paddingBottom: BOTTOM_INSET }

  const keyExtractor = useCallback(
    (item: { comment: Comment; depth: number }) => item.comment.id,
    []
  )

  return (
    <FlatList
      ref={flatListRef}
      data={rows}
      keyExtractor={keyExtractor}
      renderItem={renderItem}
      ListHeaderComponent={ListHeaderComponent}
      ListEmptyComponent={ListHeaderComponent ? null : <EmptyState />}
      keyboardShouldPersistTaps="handled"
      showsVerticalScrollIndicator={false}
      contentInsetAdjustmentBehavior={
        scrollProps?.contentInsetAdjustmentBehavior ?? 'automatic'
      }
      contentInset={scrollProps?.contentInset}
      scrollIndicatorInsets={scrollProps?.scrollIndicatorInsets}
      contentContainerStyle={contentContainerStyle}
      style={{ backgroundColor: theme.background.val }}
    />
  )
}

function EmptyState() {
  const theme = useTheme()
  return (
    <YStack h="100%" justifyContent="center" alignItems="center" gap="$3">
      <Text fontSize="$9" fontWeight="bold" color={theme.color.val}>
        No comments yet
      </Text>
      <Text fontSize="$6" color={theme.colorSecondary.val}>
        Start the conversation
      </Text>
    </YStack>
  )
}
