import moment from 'moment';
import React, {useContext, useEffect, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {FlatList} from 'react-native-gesture-handler';
import {useDispatch, useSelector} from 'react-redux';
import {CommentContext} from '../../screens/profile/MomentCommentsScreen';
import {getComments} from '../../services';
import {updateReplyPosted} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {CommentThreadType, CommentType, ScreenType} from '../../types';
import {SCREEN_HEIGHT} from '../../utils';
import CommentTile from './CommentTile';

export type CommentsContainerProps = {
  screenType: ScreenType;
  objectId: string;
  commentId?: string;
  shouldUpdate: boolean;
  setShouldUpdate: (update: boolean) => void;
  isThread: boolean;
  setCommentsLengthParent: (length: number) => void;
};

/**
 * Comments Container to be used for both comments and replies
 */

const CommentsContainer: React.FC<CommentsContainerProps> = ({
  screenType,
  objectId,
  isThread,
  shouldUpdate,
  setShouldUpdate,
  commentId,
  setCommentsLengthParent,
}) => {
  const {setCommentsLength, commentTapped} = useContext(CommentContext);
  const {username: loggedInUsername} = useSelector(
    (state: RootState) => state.user.user,
  );
  const [commentsList, setCommentsList] = useState<CommentType[]>([]);
  const dispatch = useDispatch();
  const ref = useRef<FlatList<CommentType>>(null);
  const ITEM_HEIGHT = SCREEN_HEIGHT / 7.0;

  const countComments = (comments: CommentType[]) => {
    let count = 0;
    for (let i = 0; i < comments.length; i++) {
      count += 1 + comments[i].replies_count;
    }
    return count;
  };

  useEffect(() => {
    const loadComments = async () => {
      await getComments(objectId, isThread).then((comments) => {
        if (comments && subscribedToLoadComments) {
          setCommentsList(comments);
          if (setCommentsLength) {
            setCommentsLength(comments.length);
          }
          setShouldUpdate(false);
        }
        setCommentsLengthParent(countComments(comments));
      });
    };
    let subscribedToLoadComments = true;
    if (shouldUpdate) {
      loadComments();
    }
    return () => {
      subscribedToLoadComments = false;
    };
  }, [shouldUpdate]);

  // scrolls to the comment
  useEffect(() => {
    if (commentId) {
      const index = commentsList.findIndex(
        (item) => item.comment_id === commentId,
      );
      if (index > 0) {
        let comments = [...commentsList];
        const temp = comments[index];
        comments[index] = comments[0];
        comments[0] = temp;
        setCommentsList(comments);
      }
    } else if (!isThread && !commentTapped) {
      setTimeout(() => {
        ref.current?.scrollToEnd({animated: true});
      }, 500);
    }
    return () => {
      if (commentId && isThread) {
        setTimeout(() => {
          dispatch(updateReplyPosted(undefined));
        }, 200);
      }
    };
  }, [commentId]);

  const renderComment = ({item}: {item: CommentType | CommentThreadType}) => (
    <CommentTile
      key={item.comment_id}
      commentObject={item}
      screenType={screenType}
      isThread={isThread}
      shouldUpdateParent={shouldUpdate}
      setShouldUpdateParent={setShouldUpdate}
      canDelete={item.commenter.username === loggedInUsername}
    />
  );

  return (
    <FlatList
      data={commentsList.sort(
        (a, b) => moment(a.date_created).unix() - moment(b.date_created).unix(),
      )}
      ref={ref}
      keyExtractor={(item, index) => index.toString()}
      decelerationRate={'fast'}
      snapToAlignment={'start'}
      snapToInterval={ITEM_HEIGHT}
      renderItem={renderComment}
      showsVerticalScrollIndicator={false}
      contentContainerStyle={styles.scrollViewContent}
      getItemLayout={(data, index) => ({
        length: ITEM_HEIGHT,
        offset: ITEM_HEIGHT * index,
        index,
      })}
      pagingEnabled
    />
  );
};

const styles = StyleSheet.create({
  scrollViewContent: {
    justifyContent: 'center',
  },
});

export default CommentsContainer;
