import React, {memo, useCallback} from 'react';
import {StackActions, useNavigation} from '@react-navigation/native';
import {useDispatch} from 'react-redux';
import {Comment, CommentFooter, ReactionsSummaryComments} from '@components';
import {NewPostScreens} from '@components/_custom/NewPost/navigation';
import {useReactionsSummary} from '@hooks/useReactionsSummary';
import {CommentableType} from '@interfaces/comments';
import {Reaction} from '@interfaces/reaction';
import {FullPost} from '@modules/post/interfaces';
import {openReactionPicker} from '@modules/app/redux';
import {
  addCommentReaction,
  removeCommentReaction,
} from '@redux/comment/comment.actions';
import {usePermissions} from '@redux/selectors';
import {Screens} from '@shared/constants';
import {getIsReactionLoggedUser} from '@shared/utils';

import {styles} from './styles';

export interface PostCommentProps {
  post: FullPost;
  postId?: number;
  isMarketplace?: boolean;
  groupId?: number;
  articleId?: number;
  canComment?: boolean;
  displayLastComment?: boolean;
  handleOnPressComments?: () => void;
  canAnsweredComment?: boolean;
  onReactionPress?: (params: {
    postId: number;
    commentId: number;
    reactions: Reaction[];
    reaction: string;
  }) => void;
  isArchived?: boolean;
}

function PostComment({
  canComment,
  post,
  postId,
  displayLastComment,
  handleOnPressComments,
  isMarketplace,
  articleId,
  groupId,
  canAnsweredComment = true,
  onReactionPress: onReactionPressProp,
  isArchived,
}: PostCommentProps) {
  const {
    commentCount,
    showSegmentationUsersCount,
    segmentationUsersCount,
    lastComments,
  } = post;

  const {
    CAN_REACT_POSTS: canReactPosts,
    CAN_REACT_ARTICLES: canReactArticles,
    CAN_REACT_MARKETPLACE_POSTS: canReactMarketplacePosts,
  } = usePermissions();

  const canReact =
    (articleId && canReactArticles) ||
    (isMarketplace && canReactMarketplacePosts) ||
    (!articleId && !isMarketplace && canReactPosts);

  const {
    user: commentUser,
    createdAt = '',
    body = '',
    attachments = [],
    bodyAttributes,
    reactions = [],
    id,
    isExternal,
  } = lastComments?.[0] || {};

  const {
    firstName = '',
    lastName = '',
    profilePicture = null,
  } = commentUser || {};

  const commentableType = groupId
    ? CommentableType.GROUP_POST
    : articleId
    ? CommentableType.ARTICLE
    : isMarketplace
    ? CommentableType.MARKETPLACE
    : CommentableType.POST;

  const navigation = useNavigation();
  const dispatch = useDispatch();

  const {
    showReactionsSummary,
    selectedReaction,
    setSelectedReaction,
    onShowSummaryBottomSheet,
    onCloseReactionsSummary,
  } = useReactionsSummary();

  const onPressToComments = (autoFocus: boolean) => () => {
    if (handleOnPressComments) {
      handleOnPressComments();
    } else if (groupId) {
      navigation.navigate(Screens.GROUP_POST_DETAIL, {
        id: post.id,
        groupId,
        shouldScrollToComments: true,
        autoFocus,
      });
    } else {
      navigation.navigate(
        isMarketplace ? Screens.MARKETPLACE_POST_DETAIL : Screens.POST_DETAIL,
        {
          id: post.id,
          shouldScrollToComments: true,
          isMarketplace,
          autoFocus,
        },
      );
    }
  };

  const onAudiencePress = () => {
    navigation.navigate(Screens.PUBLISH_POST, {
      initialRouteName: NewPostScreens.SegmentationPost,
      post: post,
    });
  };

  const onDetailPress = useCallback(() => {
    if (id) {
      navigation.navigate(Screens.COMMENT_DETAIL, {
        parentCommentId: id,
        postId: postId || post.id,
        articleId,
        groupId,
        isMarketplace,
      });
    }
  }, [id, navigation, groupId, postId, isMarketplace, articleId, post.id]);

  const onTagPress = useCallback(
    (targetId: number) =>
      navigation.dispatch(
        StackActions.push(Screens.PROFILE, {userId: targetId}),
      ),
    [navigation],
  );

  const onPressCommentUser = () => commentUser && onTagPress(commentUser.id);

  const onToggleSelectNewReaction = () => {
    if (id) {
      if (onReactionPressProp) {
        dispatch(
          openReactionPicker({
            commentId: id,
            postId: postId || post.id,
            reactions: reactions || [],
            onReactionSelected: (reaction: string) =>
              onReactionPressProp({
                commentId: id,
                postId: postId || post.id,
                reaction,
                reactions,
              }),
          }),
        );

        return;
      }

      dispatch(
        openReactionPicker({
          commentId: id,
          commentableType,
          postId: postId || post.id,
          groupId,
          parentId: undefined,
          reactions,
          shouldUpdateLastComment: true,
          isMarketplace,
        }),
      );
    }
  };

  const toggleReactionsListDrawer = (reaction?: string) => {
    if (id) {
      onShowSummaryBottomSheet(reaction);
    }
  };

  const onReactionPress = useCallback(
    (reaction: string) => {
      if (id) {
        if (onReactionPressProp) {
          onReactionPressProp({
            postId: postId || post.id,
            commentId: id,
            reactions,
            reaction,
          });
          return;
        }

        const reactionData = {
          commentableType,
          postId: postId || post.id,
          commentId: id,
          reaction,
          shouldUpdateLastComment: true,
          articleId,
          groupId,
          parentId: undefined,
          isMarketplace,
          isAcknowledgement: false,
        };

        const isReactedByUser = getIsReactionLoggedUser(
          reactions || [],
          reaction,
        );

        dispatch(
          isReactedByUser
            ? removeCommentReaction(reactionData)
            : addCommentReaction(reactionData),
        );
      }
    },
    [
      id,
      onReactionPressProp,
      commentableType,
      postId,
      post.id,
      articleId,
      groupId,
      isMarketplace,
      reactions,
      dispatch,
    ],
  );

  return canComment || !!groupId ? (
    <>
      <CommentFooter
        onPressComment={onPressToComments(true)}
        onPressFooter={onPressToComments(false)}
        commentCount={commentCount}
        canAnswerComment={canAnsweredComment}
        audienceUsersCount={
          showSegmentationUsersCount ? segmentationUsersCount : undefined
        }
        onAudiencePress={onAudiencePress}
      />
      {!!commentCount && displayLastComment && !!lastComments?.length && (
        <Comment
          isExternal={isExternal}
          canReact={canReact}
          containerStyle={styles.commentContainer}
          firstName={firstName}
          lastName={lastName}
          onPressComment={onDetailPress}
          onPressUser={onPressCommentUser}
          avatar={profilePicture}
          bodyAttributes={bodyAttributes}
          onTagPress={onTagPress}
          comment={body}
          createAt={createdAt}
          showOptions={false}
          multimediaAttachments={attachments}
          reactions={reactions}
          onToggleReactionsBottomSheet={onToggleSelectNewReaction}
          onToggleReactionsListDrawer={toggleReactionsListDrawer}
          onReactionPress={onReactionPress}
          isArchived={isArchived}
        />
      )}
      {showReactionsSummary && id && (
        <ReactionsSummaryComments
          showReactionsSummary
          setSelectedReaction={setSelectedReaction}
          reactions={reactions}
          id={id}
          selectedReaction={selectedReaction}
          onCloseReactionsSummary={onCloseReactionsSummary}
          groupId={groupId}
          postId={postId || post.id}
        />
      )}
    </>
  ) : null;
}

export default memo(PostComment);
