import {IconUser, IconUsersGroup} from '@tabler/icons-react-native';
import {AvatarProps, AvatarSize, AvatarVariant} from '@components';
import i18n from '@config/i18n';
import {HuDataMember, Conversation} from '@modules/chats/interfaces';
import {getUserInfo} from '@modules/chats/services/usersServices';
import {UsersUpdaterService} from '@modules/chats/instances/updaters';
import {getCompleteName} from '@shared/utils';

// Pixel widths matching `getImageSizes()` in
// app/shared/components/_HuGo/Avatar/styles.ts so the requested server
// variant lines up with what the Avatar component actually renders.
const AVATAR_PIXELS: Record<AvatarSize, number> = {
  xs: 24,
  sm: 32,
  md: 40,
  lg: 64,
  xl: 104,
  xxl: 128,
};

export const avatarSizeToPixels = (size?: AvatarSize): number | undefined =>
  size ? AVATAR_PIXELS[size] : undefined;

export const getUserAvatar = (
  user?: Nullable<HuDataMember>,
  currentUserId?: number,
): Omit<AvatarProps, 'name'> & {title: string; name: string} => {
  if (!user) {
    return {
      title: '',
      name: '',
      Icon: IconUser,
    };
  }

  const name = getCompleteName({
    firstName: user.first_name || '',
    lastName: user.last_name || '',
  });
  const isUserDeleted = !!user.deleted_at;
  const finalName =
    currentUserId === user.id ? `${name} (${i18n.t('chats.you')})` : name;
  const url = isUserDeleted ? undefined : user.picture_asset_url;

  // Workaround to get profile picture from file-assets and save it in the DB
  const onImageError = () => {
    if (!user.picture_asset_url) {
      // Fetch user info and update the user
      getUserInfo({user: user.id, fromServer: true})
        .then(([userInfo]) => {
          UsersUpdaterService.saveUsers([userInfo], {updateStore: true});
        })
        .catch(() => {});
    }
  };

  return {
    title: finalName,
    name: finalName,
    Icon: isUserDeleted ? IconUser : undefined,
    url,
    variant: (isUserDeleted ? 'error' : undefined) as AvatarVariant,
    withAuthHeader: !!user.picture_asset_url,
    enableCache: true,
    loaderType: 'skeleton',
    // Avatars are the single most identity-carrying piece of UI in the
    // chats list / chat header / message rows — if they load after the
    // chat tiles the experience looks "off". ExpoImage's native fetch
    // queue honours this hint: `high` puts avatar requests ahead of any
    // `normal`/`low` images (including ConversationMediaPrefetcher thumbnail
    // prefetches) fighting for the same network.
    priority: 'high',
    // Avatars are tiny — 3 s is plenty for a fresh fetch, and the
    // shared `<Image>` wrapper falls into its auto-retry funnel after
    // this elapses rather than spinning forever on a stalled request.
    timeout: 7000,
    onImageError,
  };
};

export const getChannelAvatar = (
  conversation?: Pick<
    Conversation,
    'other_user' | 'is_im' | 'is_channel' | 'picture_url' | 'name'
  >,
): Omit<AvatarProps, 'name'> & {title: string} => {
  return {
    title: conversation?.name || '',
    Icon: IconUsersGroup,
    url: conversation?.picture_url,
    variant: 'default',
    withAuthHeader: true,
    enableCache: true,
    loaderType: 'skeleton',
    // Same reasoning as getUserAvatar — see that comment.
    priority: 'high',
    // 7s timeout as user avatars — small image, no reason to
    // let it spin forever; the wrapper's auto-retry funnel handles
    // genuine stalls.
    timeout: 7000,
  };
};

export const getChatAvatar = (
  conversation?: Pick<
    Conversation,
    'other_user' | 'is_im' | 'is_channel' | 'picture_url' | 'name'
  >,
  currentUserId?: number,
) =>
  conversation?.is_im
    ? getUserAvatar(conversation.other_user, currentUserId)
    : getChannelAvatar(conversation);
