import React, {memo, useCallback, useMemo} from 'react';
import {StyleSheet, View, ViewStyle} from 'react-native';
import {IconMoodPlus} from '@tabler/icons-react-native';
import {useDispatch} from 'react-redux';
import {Pressable, Typography} from '@components';
import {CHATS_SPACING, getReactionsHeight} from '@modules/chats/utils';
import {showReactionList, useReactionSummary} from '@modules/chats/store';
import {
  MAX_REACTIONS_FOR_MESSAGE,
  MAX_REACTIONS_PER_LINE,
} from '@modules/chats/constants';
import {openReactionPicker} from '@modules/app/redux/actions';
import {useMessageActions} from '@modules/chats/hooks';
import {ReactionsMessage} from '@modules/chats/interfaces';
import {BORDER_RADIUS, ICON_SIZES, useTheme} from '@shared/theme';

interface Props {
  item: ReactionsMessage;
  interactionDisabled?: boolean;
}

function MessageReactions({item, interactionDisabled}: Props) {
  const {clientMsgId, messageTs, channel, isSentByCurrentUser} = item.data;
  const withExtraMargin = item.isChannel;
  const {theme} = useTheme();
  const dispatch = useDispatch();
  const {toggleReaction} = useMessageActions({channel});
  const summary = useReactionSummary(clientMsgId);
  const canAddMoreEmojis =
    summary &&
    summary.length < MAX_REACTIONS_FOR_MESSAGE &&
    !interactionDisabled;
  const show = summary && summary.length > 0;

  const onReactionPress = useCallback(
    (name: string) => () => {
      toggleReaction({clientMsgId, name});
    },
    [toggleReaction, clientMsgId],
  );

  const onSeeAllPress = useCallback(
    (name: string) => () => {
      if (messageTs) {
        showReactionList({
          channel,
          clientMsgId,
          ts: messageTs,
          initialTab: name,
        });
      }
    },
    [channel, clientMsgId, messageTs],
  );

  const onAddMorePress = () => {
    dispatch(
      openReactionPicker({
        channel,
        clientMsgId,
        reactions: [],
      }),
    );
  };

  const reactionRows = useMemo(() => {
    if (!summary?.length) return [];

    const rows = [];
    for (let i = 0; i < summary.length; i += MAX_REACTIONS_PER_LINE) {
      rows.push(summary.slice(i, i + MAX_REACTIONS_PER_LINE));
    }
    if (
      canAddMoreEmojis &&
      rows[rows.length - 1].length === MAX_REACTIONS_PER_LINE
    ) {
      rows.push([]);
    }

    return rows;
  }, [canAddMoreEmojis, summary]);

  const heightStyle = useMemo((): ViewStyle => {
    if (!show) {
      return {
        height: 0,
      };
    }

    return {
      height: getReactionsHeight(summary.length),
    };
  }, [summary, show]);

  const alignStyle = useMemo((): ViewStyle => {
    return isSentByCurrentUser
      ? {
          marginLeft: 'auto',
          paddingRight: CHATS_SPACING.scrollPadding,
          overflow: 'hidden',
        }
      : {
          overflow: 'hidden',
          marginRight: 'auto',
          paddingLeft: withExtraMargin
            ? CHATS_SPACING.avatarHeight +
              CHATS_SPACING.gap +
              CHATS_SPACING.scrollPadding
            : CHATS_SPACING.scrollPadding,
        };
  }, [isSentByCurrentUser, withExtraMargin]);

  return (
    <View style={alignStyle} testID="reaction-container">
      <View style={[styles.container, heightStyle]}>
        {reactionRows.map((row, rowIndex) => (
          <View
            key={rowIndex}
            style={[
              styles.reactions,
              isSentByCurrentUser && styles.reactionsRight,
            ]}>
            {row.map(reaction => (
              <Pressable
                key={reaction.name}
                disabled={interactionDisabled}
                testID={`reaction-${reaction.name}`}
                onPress={onReactionPress(reaction.name)}
                onLongPress={onSeeAllPress(reaction.name)}
                style={[
                  styles.reaction,
                  {
                    borderColor: theme.background.layout.tertiary,
                    backgroundColor: theme.background.layout.tertiary,
                  },
                  reaction.hasUserReaction && {
                    borderColor: theme.button.background.primary.hover,
                    backgroundColor: theme.background.layout.brand,
                  },
                ]}>
                <Typography
                  variant="xxs"
                  weight="semiBold"
                  allowFontScaling={false}>
                  {reaction.text}
                </Typography>
              </Pressable>
            ))}
            {canAddMoreEmojis && rowIndex === reactionRows.length - 1 && (
              <Pressable
                style={[
                  styles.addMore,
                  {
                    borderColor: theme.border.neutral.default,
                    backgroundColor: theme.background.layout.tertiary,
                  },
                ]}
                testID="open-reaction-dialog"
                onPress={onAddMorePress}>
                <IconMoodPlus
                  size={ICON_SIZES.x4}
                  color={theme.text.neutral.default}
                />
              </Pressable>
            )}
          </View>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    gap: CHATS_SPACING.smallGap,
    overflow: 'hidden',
    justifyContent: 'center',
  },
  reactions: {
    flexDirection: 'row',
    gap: CHATS_SPACING.smallGap,
    alignItems: 'center',
  },
  reaction: {
    paddingVertical: CHATS_SPACING.smallGap,
    paddingHorizontal: CHATS_SPACING.gap,
    borderRadius: BORDER_RADIUS.m,
    justifyContent: 'center',
    alignItems: 'center',
    borderWidth: 1.5,
    height: CHATS_SPACING.reactionsHeight,
  },
  addMore: {
    paddingVertical: CHATS_SPACING.smallGap,
    paddingHorizontal: CHATS_SPACING.gap,
    borderRadius: BORDER_RADIUS.m,
    borderWidth: 1.5,
    height: CHATS_SPACING.reactionsHeight,
    alignItems: 'center',
    justifyContent: 'center',
  },
  reactionsRight: {
    justifyContent: 'flex-end',
  },
});

export default memo(MessageReactions);
