import React, {useCallback, useEffect} from 'react';
import {StyleProp, View, ViewStyle} from 'react-native';
import {useDispatch} from 'react-redux';
import {SocketConnection} from '@config/socket/socket';
import {EventsSocketsType} from '@config/constants';
import {StreamReaction} from '@modules/livestream/interfaces';
import {
  addStreamReaction,
  removeStreamReaction,
} from '@modules/livestream/store';
import {useAppSelector} from '@redux/utils';
import {commonStyles} from '@shared/styles';

import FloatingReaction from './components/FloatingReaction';

const socket = new SocketConnection();

interface Props {
  style?: StyleProp<ViewStyle>;
}

export function Reactions({style}: Props) {
  const dispatch = useDispatch();
  const reactions = useAppSelector(({livestream}) => livestream.post.reactions);

  const onAnimationFinish = useCallback(
    (reaction: StreamReaction) => {
      dispatch(removeStreamReaction(reaction.id));
    },
    [dispatch],
  );

  /**
   * Effect to listen reactions socket event
   */
  useEffect(() => {
    socket.listenEvent(
      EventsSocketsType.LIVESTREAM_NEW_REACTION,
      (data: StreamReaction) => {
        dispatch(addStreamReaction(data));
      },
    );
    return () => {
      socket.unListenEvent(EventsSocketsType.LIVESTREAM_NEW_REACTION);
    };
  }, [dispatch]);

  return (
    <View style={[commonStyles.absolute, style]}>
      {reactions.map((reaction, index) => (
        <FloatingReaction
          key={reaction.id}
          reaction={reaction}
          onAnimationFinish={onAnimationFinish}
          zOrder={index}
        />
      ))}
    </View>
  );
}
