import { memo, useMemo } from 'react';

import Stack, { StackProps } from '@material-hu/mui/Stack';

import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { MAX_EMOJIS } from 'src/types/feed';
import { Reaction as ReactionType } from 'src/types/reaction';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';
import { sortReactions } from 'src/utils/reactions';

import {
  REACTION_BUTTON_HEIGHT,
  REACTION_BUTTON_WIDTH,
  ReactionAdd,
} from 'src/components/dashboard/reactions';
import { invalidateReactionUserList } from 'src/components/dashboard/reactions/queries';
import Reaction from 'src/components/dashboard/reactions/Reaction';
import ReactionTooltip from 'src/components/dashboard/reactions/ReactionTooltip';

import UsersListDrawer from './UsersListDrawer';
import { GenericGetReactionUsersFunction } from './UsersListDrawer/ReactionUsersList';

export type ReactionListProps = {
  id: number;
  reactions: ReactionType[];
  onAdd?: (emoji: string, unified: string) => any;
  onRemove?: (emoji: string) => any;
  withAdd?: boolean;
  disabled?: boolean;
  limit?: number;
  defaultEmoji?: { emoji: string; unified: string };
  withUserList?: boolean;
  addButtonVariant?: 'button' | 'icon';
  maxEmojis?: number;
  stackProps?: StackProps;
  containerElement?: HTMLDivElement | null;
  getReactionUsers: GenericGetReactionUsersFunction;
};

const ReactionsList = (props: ReactionListProps) => {
  const {
    id,
    reactions,
    getReactionUsers,
    onAdd = () => null,
    onRemove = () => null,
    withUserList = false,
    addButtonVariant = 'button',
    withAdd = true,
    disabled = false,
    limit = null,
    defaultEmoji,
    maxEmojis = MAX_EMOJIS,
    stackProps,
    containerElement,
  } = props;

  const { t } = useTranslation('web_only');
  const HugoThemeProvider = useHuGoTheme();
  const showGeneralError = useGeneralError();

  const processedReactions = useMemo(() => {
    const activeReactions =
      reactions?.filter(reaction => reaction.count > 0) || [];
    const hasActiveReactions = activeReactions.length > 0;

    if (!defaultEmoji || hasActiveReactions) return activeReactions;

    // Only add default emoji if there are no active reactions
    const reactionsCopy = reactions ? [...reactions] : [];
    const findIndex = reactionsCopy.findIndex(
      reaction => reaction.emoji === defaultEmoji.emoji,
    );

    if (findIndex === -1) {
      reactionsCopy.push({
        count: 0,
        emoji: defaultEmoji.emoji,
        unified: defaultEmoji.unified,
      });
    }

    sortReactions(reactionsCopy, defaultEmoji.emoji);
    return reactionsCopy;
  }, [defaultEmoji, JSON.stringify(reactions)]);

  const handleAdd = async (emoji: string, unified: string) => {
    try {
      await onAdd(emoji, unified);
      invalidateReactionUserList(id, emoji);
    } catch (err) {
      showGeneralError(err, t('reactions.add_reaction_error'));
    }
  };

  const handleRemove = async (emoji: string) => {
    try {
      await onRemove(emoji);
      invalidateReactionUserList(id, emoji);
    } catch (err) {
      showGeneralError(err, t('reactions.remove_reaction_error'));
    }
  };

  const filterReactions = limit
    ? processedReactions?.slice(0, limit)
    : processedReactions;

  const showUsersListDrawer =
    filterReactions &&
    filterReactions.some(reaction => reaction.count > 0) &&
    withUserList;

  return (
    <HugoThemeProvider>
      <Stack
        {...stackProps}
        sx={{
          alignItems: 'center',
          flexDirection: 'row',
          flexWrap: 'wrap',
          justifyContent: 'flex-start',
          gap: 1,
          mt: 1.5,
          ...(stackProps?.sx || {}),
        }}
      >
        {filterReactions?.map(reaction => (
          <ReactionTooltip
            key={reaction.emoji}
            id={id}
            reaction={reaction}
            getReactionUsers={getReactionUsers}
            popperProps={{
              container: containerElement,
            }}
          >
            <Reaction
              reaction={reaction}
              onAdd={handleAdd}
              onRemove={handleRemove}
              disabled={disabled}
            />
          </ReactionTooltip>
        ))}
        {withAdd && (
          <ReactionAdd
            onAdd={handleAdd}
            disabled={disabled || processedReactions?.length >= maxEmojis}
            variant={addButtonVariant}
            buttonSize={{
              width: REACTION_BUTTON_WIDTH,
              height: REACTION_BUTTON_HEIGHT,
            }}
            tooltipProps={{
              slotProps: {
                popper: {
                  container: containerElement,
                },
              },
            }}
          />
        )}

        {showUsersListDrawer && (
          <UsersListDrawer
            id={id}
            filterReactions={filterReactions}
            getReactionUsers={getReactionUsers}
            container={containerElement}
          />
        )}
      </Stack>
    </HugoThemeProvider>
  );
};

export default memo(ReactionsList);
