import { Feather } from '@expo/vector-icons'
import { Pressable } from 'react-native'
import ImageComponent from 'src/components/ImageComponent'
import type { PreviewCard, Status } from 'src/lib/api-types'
import { openBrowserAsync } from 'src/utils'
import { Text, useTheme, View, XStack, YStack } from 'tamagui'

// The server's `preview_card` slot is still stubbed on stock Pixelfed
// (ApiV1Controller.php:3533 returns `{}` and StatusTransformer sets
// `'card' => null`), so on most instances `card` is `null` and this
// component renders nothing. When the server patch that populates
// `status.card` lands — part of Batch C's Halflight "link previews"
// module — feed cells will start surfacing OpenGraph metadata automatically.
//
// The api-types file types `Status['card']` as `Array<PreviewCard>` but
// Mastodon's canonical shape is a single object. We accept both and pick
// the first entry defensively so neither shape breaks rendering.
type CardInput = Status['card'] | PreviewCard | null | undefined

export default function LinkPreviewCard({ card }: { card: CardInput }) {
  const c = normalizeCard(card)
  const theme = useTheme()
  if (!c || !c.url || !c.title) return null

  const host = c.provider_name?.trim() || hostFromUrl(c.url)
  const usesHero =
    !!c.image &&
    (c.type === 'rich' ||
      c.type === 'photo' ||
      c.type === 'video' ||
      (c.width ?? 0) >= 500)

  return (
    <Pressable
      onPress={() => openBrowserAsync(c.url)}
      style={({ pressed }) => ({ opacity: pressed ? 0.85 : 1 })}
    >
      <View
        borderWidth={1}
        borderColor={theme.borderColor.val}
        borderRadius={10}
        overflow="hidden"
        backgroundColor={theme.backgroundSecondary.val}
      >
        {usesHero && c.image ? (
          <View style={{ width: '100%', aspectRatio: 16 / 9 }}>
            <ImageComponent
              source={{ uri: c.image, width: 800, height: 420 }}
              style={{ width: '100%', height: '100%' }}
              resizeMode={'cover' as any}
              accessibilityLabel={c.title}
            />
            {c.type === 'video' ? (
              <View
                position="absolute"
                top={0}
                left={0}
                right={0}
                bottom={0}
                alignItems="center"
                justifyContent="center"
                pointerEvents="none"
              >
                <View
                  style={{
                    shadowColor: '#000',
                    shadowOffset: { width: 0, height: 2 },
                    shadowOpacity: 0.45,
                    shadowRadius: 6,
                    elevation: 6,
                  }}
                >
                  <Feather name="play-circle" size={56} color="#fff" />
                </View>
              </View>
            ) : null}
          </View>
        ) : null}
        <XStack gap="$3" p="$3" alignItems="center">
          {!usesHero && c.image ? (
            <ImageComponent
              source={{ uri: c.image, width: 120, height: 120 }}
              style={{ width: 60, height: 60, borderRadius: 6 }}
              resizeMode={'cover' as any}
              accessibilityLabel={c.title}
            />
          ) : null}
          <YStack flex={1} gap="$1">
            {host ? (
              <Text
                fontSize="$1"
                color={theme.colorTertiary.val}
                numberOfLines={1}
                textTransform="uppercase"
                letterSpacing={0.4}
                fontWeight="600"
              >
                {host}
              </Text>
            ) : null}
            <Text
              fontSize="$4"
              fontWeight="600"
              color={theme.color.val}
              numberOfLines={2}
            >
              {c.title}
            </Text>
            {c.description ? (
              <Text fontSize="$3" color={theme.colorSecondary.val} numberOfLines={2}>
                {c.description}
              </Text>
            ) : null}
          </YStack>
        </XStack>
      </View>
    </Pressable>
  )
}

function normalizeCard(input: CardInput): PreviewCard | null {
  if (!input) return null
  if (Array.isArray(input)) return input[0] ?? null
  return input
}

function hostFromUrl(url: string): string {
  try {
    return new URL(url).hostname.replace(/^www\./, '')
  } catch {
    return ''
  }
}
