import { Image } from 'expo-image';
import {
  StyleSheet,
  Text,
  View,
  type ImageStyle,
  type StyleProp,
  type ViewStyle,
} from 'react-native';

import { Catamaran, FunnelSans } from '@/constants/fonts';
import { Palette } from '@/constants/palette';
import { Radius } from '@/constants/styles';

type AvatarSize = 'sm' | 'md' | 'lg';

type AvatarProps = {
  uri?: string | null;
  name?: string | null;
  size?: AvatarSize;
  style?: StyleProp<ImageStyle>;
};

const avatarSizeMap = {
  sm: 40,
  md: 64,
  lg: 104,
} as const;

function getInitials(name?: string | null) {
  if (!name?.trim()) {
    return '?';
  }

  const parts = name
    .trim()
    .split(/\s+/)
    .slice(0, 2);

  return parts.map((part) => part[0]?.toUpperCase() ?? '').join('') || '?';
}

export function Avatar({ uri, name, size = 'md', style }: AvatarProps) {
  const avatarSize = avatarSizeMap[size];
  const initials = getInitials(name);

  if (uri) {
    return (
      <Image
        contentFit="cover"
        source={{ uri }}
        style={[
          styles.base,
          {
            width: avatarSize,
            height: avatarSize,
            borderRadius: avatarSize / 2,
          },
          style,
        ]}
      />
    );
  }

  return (
    <View
      style={[
        styles.base,
        styles.fallback,
        {
          width: avatarSize,
          height: avatarSize,
          borderRadius: avatarSize / 2,
        },
        style,
      ]}
    >
      <Text style={[size === 'lg' ? styles.largeText : styles.text]}>{initials}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  base: {
    overflow: 'hidden',
  },
  fallback: {
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: Palette.black,
    borderWidth: 1,
    borderColor: Palette.gray,
  },
  text: {
    ...FunnelSans.semiBold14,
    color: Palette.white,
  },
  largeText: {
    ...Catamaran.bold18,
    color: Palette.white,
  },
});

export default Avatar;
