import { Reaction } from 'src/types/reaction';

const MAX_USER_TO_SHOW = 20;
const MAX_USER_TO_SHOW_IN_RESPONSIVE = 5;

export const canAddReaction = (list: Reaction[], emoji: string) => {
  if (!list) return true;

  const index = list.findIndex(reaction => reaction.emoji === emoji);

  if (index === -1) {
    return true;
  }
  return !list[index].isLoggedUserReaction;
};

export const addReaction = (
  list: Reaction[] | undefined,
  emoji: string,
  unified?: string,
  isLoggedUserReaction: boolean = true,
): Reaction[] => {
  const newList: Reaction[] = list ? [...list] : [];

  const index = newList.findIndex(reaction => reaction.emoji === emoji);
  if (index === -1) {
    const newReaction = {
      emoji,
      unified,
      count: 1,
      isLoggedUserReaction,
    };

    newList.push(newReaction);

    return newList;
  }

  const oldReaction = newList[index];
  const newReaction = { ...oldReaction };

  if (!isLoggedUserReaction) {
    newReaction.count++;
  } else if (!oldReaction.isLoggedUserReaction) {
    newReaction.count++;
    newReaction.isLoggedUserReaction = true;
  }

  newList.splice(index, 1, newReaction);

  return newList;
};

export const removeReaction = (
  list: Reaction[] | undefined,
  emoji: string,
  isLoggedUserReaction: boolean = true,
): Reaction[] => {
  const newList: Reaction[] = list ? [...list] : [];

  const index = newList.findIndex(reaction => reaction.emoji === emoji);
  if (index === -1) {
    return newList;
  }

  const oldReaction = newList[index];
  let newCount = oldReaction.count;

  if (!isLoggedUserReaction) {
    newCount -= 1;
  } else if (oldReaction.isLoggedUserReaction) {
    newCount -= 1;
  }

  if (newCount > 0 || emoji === '👍') {
    const newReaction = {
      ...oldReaction,
      count: newCount,
      isLoggedUserReaction: isLoggedUserReaction
        ? false
        : oldReaction.isLoggedUserReaction,
    };

    newList.splice(index, 1, newReaction);

    return newList;
  }

  newList.splice(index, 1);

  return newList;
};

export const compareReactions = (a: Reaction, b: Reaction): number => {
  const strcmp = Intl.Collator().compare;

  if (b.count < a.count) {
    return -1;
  }

  if (b.count > a.count) {
    return 1;
  }

  return strcmp(b.emoji, a.emoji);
};

export const sortReactions = (list: Reaction[], defaultEmoji = '') => {
  list?.sort(compareReactions);

  if (!defaultEmoji) return list;

  const element = list.find(item => item.emoji === defaultEmoji);
  if (element) {
    const index = list.indexOf(element);
    list.splice(index, 1);
    list.unshift(element);
  }
  return list;
};

export const getReactionList = (reactionList: string[], maxHeight: boolean) => {
  if (reactionList.length > MAX_USER_TO_SHOW) {
    return reactionList.slice(
      0,
      maxHeight ? MAX_USER_TO_SHOW_IN_RESPONSIVE : MAX_USER_TO_SHOW,
    );
  }

  if (reactionList.length <= MAX_USER_TO_SHOW_IN_RESPONSIVE) {
    return reactionList;
  }

  return reactionList.slice(
    0,
    maxHeight ? MAX_USER_TO_SHOW_IN_RESPONSIVE : reactionList.length,
  );
};
