/* eslint-disable radix */
import React, {Fragment, useEffect, useRef, useState} from 'react';
import {Alert, Animated, StyleSheet} from 'react-native';
import {Text, View} from 'react-native-animatable';
import {RectButton, TouchableOpacity} from 'react-native-gesture-handler';
import Swipeable from 'react-native-gesture-handler/Swipeable';
import {useSelector} from 'react-redux';
import Arrow from '../../assets/icons/back-arrow-colored.svg';
import ClockIcon from '../../assets/icons/clock-icon-01.svg';
import Trash from '../../assets/ionicons/trash-outline.svg';
import {TAGG_LIGHT_BLUE} from '../../constants';
import {ERROR_FAILED_TO_DELETE_COMMENT} from '../../constants/strings';
import {deleteComment, getCommentsCount} from '../../services';
import {RootState} from '../../store/rootReducer';
import {CommentType, ScreenType, TypeOfComment} from '../../types';
import {getTimePosted, normalize, SCREEN_WIDTH} from '../../utils';
import {mentionPartTypes, renderValue} from '../../utils/comments';
import {ProfilePreview} from '../profile';
import CommentsContainer from './CommentsContainer';

/**
 * Displays users's profile picture, comment posted by them and the time difference between now and when a comment was posted.
 */

interface CommentTileProps {
  comment_object: CommentType;
  screenType: ScreenType;
  typeOfComment: TypeOfComment;
  setCommentObjectInFocus?: (comment: CommentType | undefined) => void;
  newCommentsAvailable: boolean;
  setNewCommentsAvailable: (available: boolean) => void;
  canDelete: boolean;
}

const CommentTile: React.FC<CommentTileProps> = ({
  comment_object,
  screenType,
  typeOfComment,
  setCommentObjectInFocus,
  newCommentsAvailable,
  setNewCommentsAvailable,
  canDelete,
}) => {
  const timePosted = getTimePosted(comment_object.date_created);
  const [showReplies, setShowReplies] = useState<boolean>(false);
  const [showKeyboard, setShowKeyboard] = useState<boolean>(false);
  const [newThreadAvailable, setNewThreadAvailable] = useState(true);
  const swipeRef = useRef<Swipeable>(null);
  const isThread = typeOfComment === 'Thread';

  const {replyPosted} = useSelector((state: RootState) => state.user);

  /**
   * Bubbling up, for handling a new comment in a thread.
   */
  useEffect(() => {
    if (newCommentsAvailable) {
      setNewThreadAvailable(true);
    }
  }, [newCommentsAvailable]);

  useEffect(() => {
    if (replyPosted && typeOfComment === 'Comment') {
      if (replyPosted.parent_comment.comment_id === comment_object.comment_id) {
        setShowReplies(true);
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [replyPosted]);

  /**
   * Case : A COMMENT IS IN FOCUS && REPLY SECTION IS HIDDEN
   *     Bring the current comment to focus
   * Case : No COMMENT IS IN FOCUS && REPLY SECTION IS SHOWN
   *     Unfocus comment in focus
   */
  const toggleAddComment = () => {
    //Do not allow user to reply to a thread
    if (!isThread) {
      if (setCommentObjectInFocus) {
        if (!showKeyboard) {
          setCommentObjectInFocus(comment_object);
        } else {
          setCommentObjectInFocus(undefined);
        }
      }
      setShowKeyboard(!showKeyboard);
    }
  };

  const toggleReplies = async () => {
    if (showReplies) {
      //To update count of replies in case we deleted a reply
      comment_object.replies_count = parseInt(
        await getCommentsCount(comment_object.comment_id, true),
      );
    }
    setNewThreadAvailable(true);
    setShowReplies(!showReplies);
  };

  /**
   * Method to compute text to be shown for replies button
   */
  const getRepliesText = () =>
    showReplies
      ? 'Hide'
      : comment_object.replies_count > 0
      ? `Replies (${comment_object.replies_count})`
      : 'Replies';

  const renderRightAction = (text: string, color: string) => {
    const pressHandler = async () => {
      swipeRef.current?.close();
      const success = await deleteComment(comment_object.comment_id, isThread);
      if (success) {
        setNewCommentsAvailable(true);
      } else {
        Alert.alert(ERROR_FAILED_TO_DELETE_COMMENT);
      }
    };
    return (
      <Animated.View>
        <RectButton
          style={[styles.rightAction, {backgroundColor: color}]}
          onPress={pressHandler}>
          <Trash width={normalize(25)} height={normalize(25)} color={'white'} />
          <Text style={styles.actionText}>{text}</Text>
        </RectButton>
      </Animated.View>
    );
  };

  const renderRightActions = (_: Animated.AnimatedInterpolation) =>
    canDelete ? (
      <View style={styles.swipeActions}>
        {renderRightAction('Delete', '#c42634')}
      </View>
    ) : (
      <Fragment />
    );

  return (
    <Swipeable
      ref={swipeRef}
      renderRightActions={renderRightActions}
      rightThreshold={40}
      friction={2}
      containerStyle={styles.swipableContainer}>
      <View
        style={[styles.container, isThread ? styles.moreMarginWithThread : {}]}>
        <ProfilePreview
          profilePreview={comment_object.commenter}
          previewType={'Comment'}
          screenType={screenType}
        />
        <TouchableOpacity style={styles.body} onPress={toggleAddComment}>
          <View style={styles.comment}>
            {renderValue(comment_object.comment, mentionPartTypes)}
          </View>
          <View style={styles.clockIconAndTime}>
            <ClockIcon style={styles.clockIcon} />
            <Text style={styles.date_time}>{' ' + timePosted}</Text>
            <View style={styles.flexer} />
          </View>
        </TouchableOpacity>
        {/*** Show replies text only if there are some replies present */}
        {typeOfComment === 'Comment' && comment_object.replies_count > 0 && (
          <TouchableOpacity
            style={styles.repliesTextAndIconContainer}
            onPress={toggleReplies}>
            <Text style={styles.repliesText}>{getRepliesText()}</Text>
            <Arrow
              width={12}
              height={11}
              color={TAGG_LIGHT_BLUE}
              style={
                !showReplies ? styles.repliesDownArrow : styles.repliesUpArrow
              }
            />
          </TouchableOpacity>
        )}
      </View>

      {/*** Show replies if toggle state is true */}
      {showReplies && (
        <View>
          <CommentsContainer
            objectId={comment_object.comment_id}
            screenType={screenType}
            setNewCommentsAvailable={setNewThreadAvailable}
            newCommentsAvailable={newThreadAvailable}
            typeOfComment={'Thread'}
            commentId={replyPosted?.comment_id}
          />
        </View>
      )}
    </Swipeable>
  );
};

const styles = StyleSheet.create({
  container: {
    borderBottomWidth: 1,
    borderColor: 'lightgray',
    backgroundColor: 'white',
    flexDirection: 'column',
    flex: 1,
    paddingTop: '3%',
    paddingBottom: '5%',
    marginLeft: '7%',
  },
  swipeActions: {
    flexDirection: 'row',
  },
  moreMarginWithThread: {
    marginLeft: '14%',
  },
  body: {
    marginLeft: 56,
  },
  comment: {
    marginBottom: '2%',
    marginRight: '2%',
  },
  date_time: {
    color: 'gray',
    fontSize: normalize(12),
  },
  clockIcon: {
    width: 12,
    height: 12,
    alignSelf: 'center',
  },
  clockIconAndTime: {
    flexDirection: 'row',
    marginTop: '3%',
  },
  flexer: {
    flex: 1,
  },
  repliesTextAndIconContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginTop: '5%',
    marginLeft: 56,
  },
  repliesText: {
    color: TAGG_LIGHT_BLUE,
    fontWeight: '500',
    fontSize: normalize(12),
    marginRight: '1%',
  },
  repliesBody: {
    width: SCREEN_WIDTH,
  },
  repliesDownArrow: {
    transform: [{rotate: '270deg'}],
    marginTop: '1%',
  },
  repliesUpArrow: {
    transform: [{rotate: '90deg'}],
    marginTop: '1%',
  },
  actionText: {
    color: 'white',
    fontSize: normalize(12),
    fontWeight: '500',
    backgroundColor: 'transparent',
    paddingHorizontal: '5%',
    marginTop: '5%',
  },
  rightAction: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
    flexDirection: 'column',
  },
  swipableContainer: {
    backgroundColor: 'white',
  },
});

export default CommentTile;
