import {useNavigation} from '@react-navigation/native';
import React, {useContext, useEffect, useRef, useState} from 'react';
import {
  Image,
  KeyboardAvoidingView,
  Platform,
  StatusBar,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableWithoutFeedback,
  View,
} from 'react-native';
import Animated, {EasingNode} from 'react-native-reanimated';
import {useDispatch, useSelector, useStore} from 'react-redux';
import {headerBarOptions} from '../../routes';
import {MomentContext} from '../../screens/profile/IndividualMoment';
import {deleteMomentTag, loadMomentTags} from '../../services';
import {loadUserMoments} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {MomentPostType, MomentTagType, ScreenType, UserType} from '../../types';
import {
  getTimePosted,
  HeaderHeight,
  isIPhoneX,
  navigateToProfile,
  normalize,
  SCREEN_HEIGHT,
  SCREEN_WIDTH,
} from '../../utils';
import {mentionPartTypes, renderTextWithMentions} from '../../utils/comments';
import {AddComment} from '../comments';
import CommentsCount from '../comments/CommentsCount';
import {MomentTags} from '../common';
import {MomentMoreInfoDrawer, TaggAvatar} from '../profile';
import IndividualMomentTitleBar from './IndividualMomentTitleBar';
interface MomentPostProps {
  moment: MomentPostType;
  userXId: string | undefined;
  screenType: ScreenType;
}

const MomentPost: React.FC<MomentPostProps> = ({
  moment,
  userXId,
  screenType,
}) => {
  const navigation = useNavigation();
  const dispatch = useDispatch();
  const {userId: loggedInUserId, username: loggedInUsername} = useSelector(
    (state: RootState) => state.user.user,
  );
  const {user} = useSelector((state: RootState) =>
    userXId ? state.userX[screenType][userXId] : state.user,
  );
  const state: RootState = useStore().getState();
  const isOwnProfile = user.username === loggedInUsername;

  const [tags, setTags] = useState<MomentTagType[]>([]);
  const [visible, setVisible] = useState(false);
  const [drawerVisible, setDrawerVisible] = useState(false);
  const [hideText, setHideText] = useState(false);

  const [fadeValue, setFadeValue] = useState<Animated.Value<number>>(
    new Animated.Value(0),
  );
  const [commentCount, setCommentCount] = useState<number>(
    moment.comments_count,
  );
  const [aspectRatio, setAspectRatio] = useState<number>(1);
  const [momentTagId, setMomentTagId] = useState<string>('');

  const imageRef = useRef(null);
  const {keyboardVisible} = useContext(MomentContext);

  /*
   * Load tags on initial render to pass tags data to moment header and content
   */
  useEffect(() => {
    loadMomentTags(moment.moment_id).then((response) => {
      setTags(response ? response : []);
    });
  }, [moment]);

  /*
   * Check if loggedInUser has been tagged in the picture and set the id
   */
  useEffect(() => {
    const getMomentTagId = () => {
      const ownTag: MomentTagType[] = tags.filter(
        (tag) => tag.user.id === loggedInUserId,
      );
      if (ownTag?.length > 0) {
        setMomentTagId(ownTag[0].id);
      } else {
        setMomentTagId('');
      }
    };
    getMomentTagId();
  }, [tags]);

  /*
   * Remove tag and update the current tags
   */
  const removeTag = async () => {
    const success = await deleteMomentTag(momentTagId);
    if (success) {
      const filteredTags = tags.filter((tag) => tag.user.id !== loggedInUserId);
      setTags(filteredTags);
    }
  };

  useEffect(
    () =>
      navigation.setOptions({
        ...headerBarOptions('white', ''),
        headerTitle: () => (
          <IndividualMomentTitleBar title={moment.moment_category} />
        ),
      }),
    [moment.moment_id],
  );

  /*
   *  Determines if an image is 9:16 to set aspect ratio of current image and
   * determine if image must be displayed in full screen or not
   */
  useEffect(() => {
    Image.getSize(
      moment.moment_url,
      (w, h) => {
        setAspectRatio(w / h);
      },
      (err) => console.log(err),
    );
  }, []);

  /*
   * To animate tags display
   */
  useEffect(() => {
    const fade = async () => {
      Animated.timing(fadeValue, {
        toValue: 1,
        duration: 250,
        easing: EasingNode.linear,
      }).start();
    };
    fade();
  }, [fadeValue]);

  useEffect(() => {
    if (!keyboardVisible && hideText) {
      setHideText(false);
    }
  }, [keyboardVisible, hideText]);

  const MomentPosterPreview = () => (
    <View style={styles.momentPosterContainer}>
      <TouchableOpacity
        onPress={() =>
          navigateToProfile(state, dispatch, navigation, screenType, user)
        }
        style={styles.header}>
        <TaggAvatar
          style={styles.avatar}
          userXId={userXId}
          screenType={screenType}
          editable={false}
        />
        <Text style={styles.headerText}>{user.username}</Text>
      </TouchableOpacity>
    </View>
  );

  return (
    <>
      <StatusBar barStyle={'light-content'} />
      <View style={styles.mainContainer}>
        <View style={styles.imageContainer}>
          <Image
            source={{uri: moment.moment_url}}
            style={[
              styles.image,
              {
                height: SCREEN_WIDTH / aspectRatio,
              },
            ]}
            resizeMode={'contain'}
            ref={imageRef}
          />
        </View>
        {visible && (
          <Animated.View style={[styles.tagsContainer, {opacity: fadeValue}]}>
            <MomentTags
              editing={false}
              tags={tags}
              setTags={() => null}
              imageRef={imageRef}
            />
          </Animated.View>
        )}
        <TouchableWithoutFeedback
          onPress={() => {
            setVisible(!visible);
            setFadeValue(new Animated.Value(0));
          }}>
          <View style={styles.contentContainer}>
            <View style={styles.topContainer}>
              <MomentMoreInfoDrawer
                isOpen={drawerVisible}
                setIsOpen={setDrawerVisible}
                isOwnProfile={isOwnProfile}
                momentTagId={momentTagId}
                removeTag={removeTag}
                dismissScreenAndUpdate={() => {
                  dispatch(loadUserMoments(loggedInUserId));
                  navigation.goBack();
                }}
                screenType={screenType}
                moment={moment}
                tags={tags}
              />
            </View>
            <KeyboardAvoidingView
              behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
              keyboardVerticalOffset={-20}>
              <View style={styles.bottomContainer}>
                {tags.length > 0 && (
                  <Image
                    source={require('../../assets/icons/tag_indicate.png')}
                    style={styles.tagIcon}
                  />
                )}
                <View style={styles.commentsCountContainer}>
                  <CommentsCount moment={moment} screenType={screenType} />
                </View>
                <MomentPosterPreview />
                {!hideText && (
                  <>
                    {moment.caption !== '' &&
                      renderTextWithMentions({
                        value: moment.caption,
                        styles: styles.captionText,
                        partTypes: mentionPartTypes('white', 'caption'),
                        onPress: (userLocal: UserType) =>
                          navigateToProfile(
                            state,
                            dispatch,
                            navigation,
                            screenType,
                            userLocal,
                          ),
                      })}
                  </>
                )}
                <View>
                  <AddComment
                    placeholderText={'Add a comment here!'}
                    momentId={moment.moment_id}
                    callback={() => {
                      setCommentCount(commentCount + 1);
                    }}
                    onFocus={() => {
                      setHideText(true);
                    }}
                    isKeyboardAvoiding={false}
                    theme={'dark'}
                  />
                  <Text style={styles.text}>
                    {getTimePosted(moment.date_created)}
                  </Text>
                </View>
              </View>
            </KeyboardAvoidingView>
          </View>
        </TouchableWithoutFeedback>
      </View>
    </>
  );
};

const styles = StyleSheet.create({
  image: {
    zIndex: 0,
  },
  imageContainer: {
    height: SCREEN_HEIGHT,
    width: SCREEN_WIDTH,
    flexDirection: 'column',
    justifyContent: 'center',
    overflow: 'hidden',
  },
  text: {
    marginHorizontal: '5%',
    color: 'white',
    fontWeight: '500',
    textAlign: 'right',
    marginTop: 5,
  },
  captionText: {
    position: 'relative',
    marginHorizontal: '5%',
    color: '#ffffff',
    fontWeight: '500',
    fontSize: normalize(13),
    lineHeight: normalize(15.51),
    letterSpacing: normalize(0.6),
    marginBottom: normalize(5),
    width: SCREEN_WIDTH * 0.79,
  },
  tagIcon: {
    width: normalize(30),
    height: normalize(30),
    bottom: normalize(20),
    left: '5%',
  },
  avatar: {
    width: 48,
    aspectRatio: 1,
    borderRadius: 100,
    marginLeft: '3%',
  },
  headerText: {
    fontSize: 15,
    fontWeight: 'bold',
    color: 'white',
    paddingHorizontal: '3%',
  },
  header: {
    alignItems: 'center',
    flexDirection: 'row',
    marginBottom: normalize(15),
    alignSelf: 'flex-start',
  },
  momentPosterContainer: {
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
  },
  commentsCountContainer: {
    position: 'absolute',
    right: '2%',
    bottom: SCREEN_HEIGHT * 0.12,
  },
  bottomContainer: {
    flexDirection: 'column',
    justifyContent: 'flex-end',
  },
  topContainer: {
    paddingTop: isIPhoneX() ? HeaderHeight : '6%',
    alignSelf: 'flex-end',
    paddingRight: '8%',
  },
  contentContainer: {
    position: 'absolute',
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
    flexDirection: 'column',
    justifyContent: 'space-between',
    paddingBottom: '24%',
  },
  tagsContainer: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    marginBottom: '3%',
  },
  mainContainer: {
    backgroundColor: 'black',
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
    flexDirection: 'column',
    justifyContent: 'center',
  },
});

export default MomentPost;
