import React, {useEffect, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {FlatList} from 'react-native-gesture-handler';
import {useDispatch, useSelector} from 'react-redux';
import CommentTile from './CommentTile';
import {getComments} from '../../services';
import {updateReplyPosted} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {CommentType, ScreenType, TypeOfComment} from '../../types';
import {SCREEN_HEIGHT} from '../../utils';
export type CommentsContainerProps = {
  screenType: ScreenType;
  //objectId can be either moment_id or comment_id
  objectId: string;
  commentId?: string;
  setCommentsLength?: (count: number) => void;
  newCommentsAvailable: boolean;
  setNewCommentsAvailable: (value: boolean) => void;
  typeOfComment: TypeOfComment;
  setCommentObjectInFocus?: (comment: CommentType | undefined) => void;
  commentObjectInFocus?: CommentType;
};

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

const CommentsContainer: React.FC<CommentsContainerProps> = ({
  screenType,
  objectId,
  setCommentsLength,
  newCommentsAvailable,
  setNewCommentsAvailable,
  typeOfComment,
  setCommentObjectInFocus,
  commentObjectInFocus,
  commentId,
}) => {
  const {username: loggedInUsername} = useSelector(
    (state: RootState) => state.user.user,
  );
  const [commentsList, setCommentsList] = useState<CommentType[]>([]);
  const dispatch = useDispatch();
  const ref = useRef<FlatList<CommentType>>(null);

  useEffect(() => {
    const loadComments = async () => {
      await getComments(objectId, typeOfComment === 'Thread').then(
        (comments) => {
          if (comments && subscribedToLoadComments) {
            setCommentsList(comments);
            if (setCommentsLength) {
              setCommentsLength(comments.length);
            }
            setNewCommentsAvailable(false);
          }
        },
      );
    };
    let subscribedToLoadComments = true;
    if (newCommentsAvailable) {
      loadComments();
    }
    return () => {
      subscribedToLoadComments = false;
    };
  }, [
    dispatch,
    objectId,
    newCommentsAvailable,
    setNewCommentsAvailable,
    setCommentsLength,
    typeOfComment,
  ]);

  // eslint-disable-next-line no-shadow
  const swapCommentTo = (commentId: string, toIndex: number) => {
    const index = commentsList.findIndex(
      (item) => item.comment_id === commentId,
    );
    if (index > 0) {
      let comments = [...commentsList];
      const temp = comments[index];
      comments[index] = comments[toIndex];
      comments[toIndex] = temp;
      setCommentsList(comments);
    }
  };

  useEffect(() => {
    //Scroll only if a new comment and not a reply was posted
    const shouldScroll = () =>
      typeOfComment === 'Comment' && !commentObjectInFocus;

    const performAction = () => {
      if (commentId) {
        swapCommentTo(commentId, 0);
      } else if (shouldScroll()) {
        setTimeout(() => {
          ref.current?.scrollToEnd({animated: true});
        }, 500);
      }
    };
    if (commentsList) {
      //Bring the relevant comment to top if a comment id is present else scroll if necessary
      performAction();
    }

    //Clean up the reply id present in store
    return () => {
      if (commentId && typeOfComment === 'Thread') {
        setTimeout(() => {
          dispatch(updateReplyPosted(undefined));
        }, 200);
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [commentsList, commentId]);

  //WIP : TODO : Bring the comment in focus above the keyboard
  // useEffect(() => {
  //   if (commentObjectInFocus && commentsList.length >= 3) {
  //     swapCommentTo(commentObjectInFocus.comment_id, 2);
  //   }
  //   // eslint-disable-next-line react-hooks/exhaustive-deps
  // }, [commentObjectInFocus]);

  const ITEM_HEIGHT = SCREEN_HEIGHT / 7.0;

  const renderComment = ({item}: {item: CommentType}) => (
    <CommentTile
      key={item.comment_id}
      comment_object={item}
      screenType={screenType}
      typeOfComment={typeOfComment}
      setCommentObjectInFocus={setCommentObjectInFocus}
      newCommentsAvailable={newCommentsAvailable}
      setNewCommentsAvailable={setNewCommentsAvailable}
      canDelete={item.commenter.username === loggedInUsername}
    />
  );

  return (
    <FlatList
      data={commentsList}
      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({
  scrollView: {},
  scrollViewContent: {
    justifyContent: 'center',
  },
});

export default CommentsContainer;
