import { useQuery } from '@tanstack/react-query'
import { router } from 'expo-router'
import { useCallback, useMemo } from 'react'
import { Pressable } from 'react-native'
import { onMentionPressMethod } from 'src/components/common/AutolinkText'
import EmojiText from 'src/components/common/EmojiText'
import StatusContent from 'src/components/common/StatusContent'
import StatusMediaPreview from 'src/components/common/StatusMediaPreview'
import UserAvatar from 'src/components/common/UserAvatar'
import { useWindowWidth } from 'src/hooks/useWindowWidth'
import type { Quote, ShallowQuote, Status } from 'src/lib/api-types'
import { postQueries } from 'src/lib/queries/posts'
import { preprocessStatusContent, timeAgo } from 'src/utils'
import { Text, useTheme, View, XStack, YStack } from 'tamagui'

const QUOTED_BODY_THRESHOLD = 120

// Cap quoted-status thumbnails so a 1:3 portrait doesn't dominate the
// quote card. Capped images crop via cover; uncapped sit at intrinsic
// aspect, which is identical-pixel under cover or contain.
const QUOTED_MEDIA_MAX_HEIGHT = 320
const QUOTED_HORIZONTAL_INSET = 20

type QuotedStatusProps = {
  quote: Quote | ShallowQuote
}

function placeholderCopy(state: Quote['state']): string | null {
  switch (state) {
    case 'pending':
      return 'Quote pending approval from the original author.'
    case 'rejected':
      return 'Quote declined by the original author.'
    case 'revoked':
      return 'The original author revoked this quote.'
    case 'deleted':
      return 'The quoted post was deleted.'
    case 'unauthorized':
      return "You don't have permission to view this quote."
    case 'blocked_account':
      return 'Quoted account is blocked.'
    case 'blocked_domain':
      return 'Quoted domain is blocked.'
    case 'muted_account':
      return 'Quoted account is muted.'
    default:
      return null
  }
}

function isDeepQuote(q: Quote | ShallowQuote): q is Quote {
  return 'quoted_status' in q && !!q.quoted_status
}

function isShallowQuote(q: Quote | ShallowQuote): q is ShallowQuote {
  return 'quoted_status_id' in q && !!q.quoted_status_id
}

export default function QuotedStatus({ quote }: QuotedStatusProps) {
  const theme = useTheme()
  const windowWidth = useWindowWidth()
  const quotedCardWidth = windowWidth - QUOTED_HORIZONTAL_INSET

  const shallowId =
    !isDeepQuote(quote) && isShallowQuote(quote)
      ? (quote as ShallowQuote).quoted_status_id
      : undefined

  const backfill = useQuery({
    ...postQueries.detail(shallowId ?? ''),
    enabled: !!shallowId && quote.state === 'accepted',
  })

  const status: Status | undefined = isDeepQuote(quote)
    ? quote.quoted_status
    : (backfill.data as Status | undefined)

  // Press handlers must sit above the early returns so the hook order stays
  // stable across the "placeholder" / "loaded status" branches. The
  // `status.account.url` dep is read lazily — when status is undefined the
  // memo runs with `''` and the resulting handler is never called.
  const accountUrl = status?.account.url ?? ''
  const mentions = status?.mentions
  const onHashtagPress = useCallback((tag: string) => {
    router.push(`/hashtag/${tag}`)
  }, [])
  const onMentionPress = useMemo(
    () =>
      onMentionPressMethod(
        (username: string) => router.push(`/profile/0?byUsername=${username}`),
        accountUrl,
        { mentions, gotoProfileById: (id: string) => router.push(`/profile/${id}`) }
      ),
    [accountUrl, mentions]
  )

  if (quote.state !== 'accepted') {
    const copy = placeholderCopy(quote.state)
    if (!copy) return null
    return <PlaceholderCard text={copy} theme={theme} />
  }

  if (!status) {
    if (backfill.isError) {
      return <PlaceholderCard text="Quoted post unavailable." theme={theme} />
    }
    return <PlaceholderCard text="Loading quoted post…" theme={theme} muted />
  }

  const captionRaw = preprocessStatusContent(status.content ?? '')
  const hasBody = !!captionRaw && captionRaw.trim().length > 0
  const hasMedia = (status.media_attachments?.length ?? 0) > 0
  const isSensitive = status.sensitive === true
  const spoilerText = status.spoiler_text?.trim() ?? ''

  return (
    <Pressable onPress={() => router.push(`/post/${status.id}`)} hitSlop={4}>
      <View
        borderWidth={1}
        borderColor={theme.borderColor.val}
        borderRadius={12}
        overflow="hidden"
        marginHorizontal={10}
        marginVertical={8}
        backgroundColor={theme.background.val}
      >
        <XStack padding={10} gap="$2" alignItems="center">
          <UserAvatar url={status.account.avatar} size="sm" />
          <YStack flexShrink={1} flexGrow={1}>
            <EmojiText
              variant="subhead"
              text={status.account.display_name?.trim() || status.account.acct}
              emojis={status.account.emojis}
              fontWeight="600"
              color={theme.colorSecondary.val}
              numberOfLines={1}
            />
            <Text fontSize="$2" color={theme.colorTertiary.val}>
              {timeAgo(status.created_at)}
            </Text>
          </YStack>
        </XStack>

        {hasMedia && !isSensitive && (
          <StatusMediaPreview
            status={status}
            width={quotedCardWidth}
            maxHeight={QUOTED_MEDIA_MAX_HEIGHT}
            borderRadius={0}
          />
        )}

        {isSensitive && (
          <View
            paddingVertical={16}
            paddingHorizontal={12}
            backgroundColor={theme.backgroundTertiary.val}
            alignItems="center"
          >
            {spoilerText ? (
              <StatusContent
                html={spoilerText}
                emojis={status.emojis}
                onHashtagPress={onHashtagPress}
                onMentionPress={onMentionPress}
                thresholdChars={QUOTED_BODY_THRESHOLD}
                disableReadMore
              />
            ) : (
              <EmojiText
                variant="body"
                text="Sensitive content — tap to view"
                color={theme.colorSecondary.val}
              />
            )}
          </View>
        )}

        {hasBody && (
          <YStack paddingHorizontal={12} paddingVertical={10}>
            <StatusContent
              html={captionRaw}
              emojis={status.emojis}
              onHashtagPress={onHashtagPress}
              onMentionPress={onMentionPress}
              thresholdChars={QUOTED_BODY_THRESHOLD}
              disableReadMore
            />
          </YStack>
        )}
      </View>
    </Pressable>
  )
}

function PlaceholderCard({
  text,
  theme,
  muted = false,
}: {
  text: string
  theme: ReturnType<typeof useTheme>
  muted?: boolean
}) {
  return (
    <View
      borderWidth={1}
      borderColor={theme.borderColor.val}
      borderRadius={12}
      marginHorizontal={10}
      marginVertical={8}
      paddingVertical={14}
      paddingHorizontal={12}
      backgroundColor={theme.backgroundTertiary.val}
      opacity={muted ? 0.7 : 1}
    >
      <Text fontSize="$3" color={theme.colorSecondary.val}>
        {text}
      </Text>
    </View>
  )
}
