import { Image } from 'expo-image'
import { Link } from 'expo-router'
import type { ReactNode } from 'react'
import { Pressable } from 'react-native'
import { Text, useTheme, View } from 'tamagui'

export type AvatarSize = 'xs' | 'sm' | 'md' | 'lg'

type SizeSpec = { px: number; font: number }

const SIZES: Record<AvatarSize, SizeSpec> = {
  xs: { px: 24, font: 12 },
  sm: { px: 32, font: 14 },
  md: { px: 40, font: 16 },
  lg: { px: 96, font: 32 },
}

type Props = {
  url?: string | null
  size?: AvatarSize
  userId?: string | number
  onPress?: () => void
  initial?: string
  borderStyle?: 'default' | 'none' | 'contrast'
  hitSlop?: number
  accessibilityLabel?: string
}

export default function UserAvatar({
  url,
  size = 'md',
  userId,
  onPress,
  initial,
  borderStyle = 'default',
  hitSlop,
  accessibilityLabel,
}: Props) {
  const theme = useTheme()
  const { px, font } = SIZES[size]

  const borderWidth = borderStyle === 'contrast' ? 2 : borderStyle === 'none' ? 0 : 1
  const borderColor =
    borderStyle === 'contrast'
      ? theme.background.val
      : borderStyle === 'none'
        ? 'transparent'
        : theme.borderColor.val

  const initialChar = initial?.trim().charAt(0).toUpperCase() || ''

  const avatar: ReactNode = (
    <View
      collapsable={false}
      width={px}
      height={px}
      borderRadius={px / 2}
      borderWidth={borderWidth}
      borderColor={borderColor}
      backgroundColor={theme.backgroundTertiary.val}
      overflow="hidden"
      alignItems="center"
      justifyContent="center"
    >
      {url ? (
        <Image
          source={{ uri: url }}
          style={{ width: px, height: px }}
          contentFit="cover"
          cachePolicy="memory-disk"
          priority="high"
          transition={180}
          accessibilityLabel={accessibilityLabel}
        />
      ) : initialChar ? (
        <Text color={theme.color.val} fontSize={font} fontWeight="600">
          {initialChar}
        </Text>
      ) : null}
    </View>
  )

  if (userId != null) {
    return (
      <Link href={`/profile/${userId}`} asChild>
        <Pressable hitSlop={hitSlop ?? 4} accessibilityLabel={accessibilityLabel}>
          {avatar}
        </Pressable>
      </Link>
    )
  }

  if (onPress) {
    return (
      <Pressable
        onPress={onPress}
        hitSlop={hitSlop ?? 4}
        accessibilityLabel={accessibilityLabel}
      >
        {avatar}
      </Pressable>
    )
  }

  return avatar
}
