import { Image, Text, View } from 'react-native';
import type { Human } from '@/api/types';
import { useAvatarUrl } from '@/hooks/use-avatar-url';
import { resolveHumanDisplay } from '@/lib/humans';
import { cn } from '@/lib/utils';

type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

interface AvatarProps {
  humanId: string | null | undefined;
  humans: Human[] | undefined;
  size?: Size;
  /** True for online presence — adds a green ring (matches desktop). */
  online?: boolean;
  /** Background ring used to separate stacked avatars from the chrome. */
  stackBg?: string;
  /** Initials shown when the human can't be resolved (e.g. a group stream). */
  fallbackInitials?: string;
  className?: string;
}

const sizeMap: Record<Size, { box: string; text: string; ring: number }> = {
  xs: { box: 'h-6 w-6', text: 'text-[9px]', ring: 1.5 },
  sm: { box: 'h-9 w-9', text: 'text-xs', ring: 2 },
  md: { box: 'h-10 w-10', text: 'text-sm', ring: 2 },
  lg: { box: 'h-16 w-16', text: 'text-xl', ring: 2.5 },
  xl: { box: 'h-24 w-24', text: 'text-3xl', ring: 3 },
};

/**
 * Human avatar: renders the profile picture when one is set (resolved to a
 * signed URL via React Query), otherwise initials. Supports an optional online
 * ring (green) and an outer stack separator ring used to keep overlapping
 * avatars distinct on busy chrome. Matches desktop's avatar + presence pattern.
 */
export function Avatar({
  humanId,
  humans,
  size = 'sm',
  online = false,
  stackBg,
  fallbackInitials,
  className,
}: AvatarProps) {
  const display = resolveHumanDisplay(humanId, humans);
  const human = humanId ? humans?.find((h) => h.id === humanId) : undefined;
  const avatarUrl = useAvatarUrl(human?.avatar_object_id);
  const dims = sizeMap[size];
  const initials =
    display.exists || fallbackInitials === undefined
      ? display.initials
      : fallbackInitials;

  return (
    <View
      className={cn(
        'bg-black/15 items-center justify-center overflow-hidden rounded-full',
        dims.box,
        className,
      )}
      style={{
        // Online ring is the priority; if not online, show the stack
        // separator ring (if requested) so adjacent avatars stay distinct.
        borderWidth: online ? dims.ring : stackBg ? dims.ring : 0,
        borderColor: online ? '#22c55e' : (stackBg ?? 'transparent'),
      }}
    >
      {avatarUrl ? (
        <Image source={{ uri: avatarUrl }} className="h-full w-full" />
      ) : (
        <Text className={cn('text-white font-semibold', dims.text)}>
          {initials}
        </Text>
      )}
    </View>
  );
}
