import ReactNativeBlobUtil from 'react-native-blob-util';
import {GiphyMedia} from '@giphy/react-native-sdk';
import {
  Icon,
  IconCamera,
  IconFile,
  IconGif,
  IconMicrophone,
  IconVideo,
} from '@tabler/icons-react-native';
import i18n from '@config/i18n';
import {generateAsset, uploadMedia} from '@modules/chats/services';
import {MediaEntity, MediaType} from '@modules/chats/interfaces';
import {calculateGifWidthAndHeight} from '@modules/chats/utils/measuring';
import {getUlid} from '@shared/utils';

const getPathByURI = (uri: string): string => {
  return uri.replace('file://', '');
};

export const getStatFromUri = async (uri: string) => {
  const stat = await ReactNativeBlobUtil.fs.stat(getPathByURI(uri));
  return {
    size: stat.size,
    filename: stat.filename,
  };
};

export const uploadAudioFile = async ({
  uri,
  durationMs,
}: {
  uri: string;
  durationMs: number;
}): Promise<MediaEntity> => {
  const stat = await getStatFromUri(uri);

  const durationMsRound = Math.round(durationMs);

  const asset = await generateAsset({
    contentType: 'audio/mp4',
    name: stat.filename || 'audio.acc',
    size: `${stat.size} Bytes`,
    type: MediaType.AUDIO,
    width: durationMsRound,
    metadata: {
      durationInMs: durationMsRound,
    },
  });

  if (!asset) {
    throw new Error('Failed to generate asset');
  }

  await uploadMedia(uri, asset.uploadUrl, asset.contentType);

  const media: MediaEntity = {
    id: asset.id.toString(),
    type: MediaType.AUDIO,
    fileAsset: asset,
    status: 'uploaded',
    contentType: asset.contentType,
    localUri: uri,
    name: asset.name!,
    sizeInBytes: stat.size,
  };

  return media;
};

export const prepareGifToSend = async (
  gif: GiphyMedia,
): Promise<MediaEntity> => {
  const {width, height} = calculateGifWidthAndHeight(gif.aspectRatio);
  const asset = await generateAsset({
    contentType: 'image/gif',
    name: 'media.gif',
    type: MediaType.GIF,
    externalReference: {
      id: gif.id,
      origin: 'GIPHY',
    },
    width: width,
    height: height,
  });
  const media: MediaEntity = {
    id: getUlid(),
    type: MediaType.GIF,
    fileAsset: asset,
    status: 'uploaded',
    contentType: 'image/gif',
    height: height,
    width: width,
    name: 'media.gif',
    sizeInBytes: 0,
    localUri: '',
  };

  return media;
};

export const getAssetsLabel = (
  assets: {format: string; filename: string}[],
): {label: string; Icon: Icon} => {
  const {images, videos} = assets.reduce(
    (acc, asset) => {
      if (asset.format === 'image') {
        acc.images++;
      } else if (asset.format === 'video') {
        acc.videos++;
      }
      return acc;
    },
    {
      images: 0,
      videos: 0,
    },
  );

  if (images && videos) {
    const multipleImages = images > 1;
    const multipleVideos = videos > 1;
    return {
      Icon: IconCamera,
      label: `${
        multipleImages
          ? i18n.t('chat.files.image', {count: images})
          : i18n.t('chat.files.one_image')
      }, ${
        multipleVideos
          ? i18n.t('chat.files.video', {count: videos})
          : i18n.t('chat.files.one_video')
      }`,
    };
  }

  if (images) {
    return {
      Icon: IconCamera,
      label: i18n.t('chat.files.image', {count: images}),
    };
  }

  if (videos) {
    return {
      Icon: IconVideo,
      label: i18n.t('chat.files.video', {count: videos}),
    };
  }

  switch (assets[0].format) {
    case 'audio':
      return {
        Icon: IconMicrophone,
        label: i18n.t('chat.files.audio'),
      };
    case 'gif':
      return {
        Icon: IconGif,
        label: i18n.t('general.gif'),
      };
    case 'file':
    default:
      return {
        Icon: IconFile,
        label: assets[0].filename,
      };
  }
};
