import {AmplitudeMessageTypes} from '../constants';
import {Asset, AssetFormat} from '../interfaces';

enum BitFormat {
  Text = 1 << 0,
  Image = 1 << 1,
  Video = 1 << 2,
  Audio = 1 << 3,
  File = 1 << 4,
  Gif = 1 << 5,
}

const formatToBit: Record<AssetFormat, BitFormat> = {
  image: BitFormat.Image,
  audio: BitFormat.Audio,
  gif: BitFormat.Gif,
  video: BitFormat.Video,
  file: BitFormat.File,
};

export const getMessageType = (
  text: string | undefined,
  attachments: Asset[] | undefined,
) => {
  if (!attachments?.length) {
    return AmplitudeMessageTypes.Text;
  }

  let mask = 0;

  if (text?.trim()) {
    mask |= BitFormat.Text;
  }

  attachments?.forEach(({metadata}) => {
    const format = metadata?.format ?? 'file';
    mask |= formatToBit[format] ?? BitFormat.File;
  });

  if (hasFormats(mask, BitFormat.Video, BitFormat.Image, BitFormat.Text)) {
    return AmplitudeMessageTypes.ImagesAndVideoAndText;
  }
  if (hasFormats(mask, BitFormat.Video, BitFormat.Image)) {
    return AmplitudeMessageTypes.ImagesAndVideo;
  }
  if (hasFormats(mask, BitFormat.Video, BitFormat.Text)) {
    return AmplitudeMessageTypes.VideoAndText;
  }
  if (hasFormats(mask, BitFormat.Video)) {
    return AmplitudeMessageTypes.Video;
  }
  if (hasFormats(mask, BitFormat.Image, BitFormat.Text)) {
    return AmplitudeMessageTypes.ImageAndText;
  }
  if (hasFormats(mask, BitFormat.Image)) {
    return AmplitudeMessageTypes.Image;
  }
  if (hasFormats(mask, BitFormat.File, BitFormat.Text)) {
    return AmplitudeMessageTypes.FileAndText;
  }
  if (hasFormats(mask, BitFormat.File)) {
    return AmplitudeMessageTypes.File;
  }
  if (hasFormats(mask, BitFormat.Audio)) {
    return AmplitudeMessageTypes.Audio;
  }
  if (hasFormats(mask, BitFormat.Gif)) {
    return AmplitudeMessageTypes.Gif;
  }
};

const hasFormats = (mask: number, ...flags: number[]) => {
  const need = flags.reduce((acc, f) => acc | f, 0);
  return (mask & need) === need;
};
