import React, {useEffect, useState, useContext} from 'react';
import {ProfilePreviewType} from '../../types';
import {
  View,
  Text,
  Image,
  StyleSheet,
  ViewProps,
  TouchableOpacity,
  Alert,
} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import RNFetchBlob from 'rn-fetch-blob';
import AsyncStorage from '@react-native-community/async-storage';
import {AVATAR_PHOTO_ENDPOINT} from '../../constants';
import {UserType} from '../../types';
import {AuthContext} from '../../routes/';
import {isUserBlocked} from '../../services';
const NO_USER: UserType = {
  userId: '',
  username: '',
};

/**
 * This component returns user's profile picture followed by username as a touchable component.
 * What happens when someone clicks on this component is partly decided by the prop isComment.
 * If isComment is true then it means that we are not displaying this tile as a part of search results.
 * And hence we do not cache the search results.
 * On the other hand, if isComment is false, then we should update the search cache. (This cache needs to be revamped to clear outdated results.)
 * In either case, we update the userBeingVisited in our AuthContext (Which can be used to make api calls later on to fetch user specific data).
 * Finally, We navigate to Profile.
 */

interface ProfilePreviewProps extends ViewProps {
  profilePreview: ProfilePreviewType;
  isComment: boolean;
}
const ProfilePreview: React.FC<ProfilePreviewProps> = ({
  profilePreview: {username, first_name, last_name, id},
  isComment,
  style,
}) => {
  const navigation = useNavigation();
  const {user: loggedInUser, logout} = React.useContext(AuthContext);
  const [avatarURI, setAvatarURI] = useState<string | null>(null);
  const [user, setUser] = useState<UserType>(NO_USER);
  useEffect(() => {
    let mounted = true;
    const loadAvatar = async () => {
      try {
        const token = await AsyncStorage.getItem('token');
        if (!token) {
          setUser(NO_USER);
          return;
        }
        const response = await RNFetchBlob.config({
          fileCache: true,
          appendExt: 'jpg',
        }).fetch('GET', AVATAR_PHOTO_ENDPOINT + `${id}/`, {
          Authorization: 'Token ' + token,
        });
        const status = response.info().status;
        if (status === 200) {
          if (mounted) {
            setAvatarURI(response.path());
          }
          return;
        }
        if (mounted) {
          setAvatarURI('');
        }
      } catch (error) {
        console.log(error);
      }
    };
    loadAvatar();
    return () => {
      mounted = false;
    };
  }, [id]);

  /**
   * Adds a searched user to the recently searched cache if they're tapped on.
   * Cache maintains 10 recently searched users, popping off the oldest one if
   * needed to make space.
   */

  const checkIfUserIsBlocked = async (userId: string) => {
    const token = await AsyncStorage.getItem('token');
    if (!token) {
      logout();
      return false;
    }
    return await isUserBlocked(userId, loggedInUser.userId, token);
  };

  const addToRecentlyStoredAndNavigateToProfile = async () => {
    let user: ProfilePreviewType = {
      id,
      username,
      first_name,
      last_name,
    };

    try {
      //If the logged in user is blocked by the user being viewed, do not proceed.
      const isUserBlocked = await checkIfUserIsBlocked(user.id);
      if (isUserBlocked) {
        Alert.alert('You cannot view this profile');
        return;
      }
      if (!isComment) {
        const jsonValue = await AsyncStorage.getItem(
          '@recently_searched_users',
        );
        let recentlySearchedList =
          jsonValue != null ? JSON.parse(jsonValue) : null;
        if (recentlySearchedList) {
          if (recentlySearchedList.length > 0) {
            if (
              recentlySearchedList.some(
                (saved_user: ProfilePreviewType) => saved_user.id === id,
              )
            ) {
              console.log('User already in recently searched.');
            } else {
              if (recentlySearchedList.length >= 10) {
                recentlySearchedList.pop();
              }
              recentlySearchedList.unshift(user);
            }
          }
        } else {
          recentlySearchedList = [user];
        }

        try {
          let recentlySearchedListString = JSON.stringify(recentlySearchedList);
          await AsyncStorage.setItem(
            '@recently_searched_users',
            recentlySearchedListString,
          );
        } catch (e) {
          console.log(e);
        }
      }

      /**
       * Navigate to profile of the user selected
       */
      navigation.push('Profile', {
        isProfileView: true,
        username: user.username,
        userId: user.id,
      });
    } catch (e) {
      console.log(e);
    }
  };

  //With @ sign if on search screen.
  const usernameToDisplay = !isComment ? '@' + username : username;
  const usernameStyle = isComment
    ? styles.commentUsername
    : styles.searchUsername;

  const avatarStyle = !isComment ? styles.searchAvatar : styles.commentAvatar;

  return (
    <TouchableOpacity
      onPress={addToRecentlyStoredAndNavigateToProfile}
      style={[styles.container, style]}>
      <Image
        style={avatarStyle}
        source={
          avatarURI
            ? {uri: avatarURI}
            : require('../../assets/images/avatar-placeholder.png')
        }
      />
      <View style={styles.nameContainer}>
        <Text style={usernameStyle}>{usernameToDisplay}</Text>
        {first_name ? (
          <Text style={styles.name}>{first_name.concat(' ', last_name)}</Text>
        ) : (
          React.Fragment
        )}
      </View>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  searchAvatar: {
    height: 60,
    width: 60,
    borderRadius: 30,
    marginRight: 15,
  },
  commentAvatar: {
    height: 40,
    width: 40,
    borderRadius: 20,
    marginRight: 15,
    marginTop: '2%',
  },
  nameContainer: {
    justifyContent: 'space-evenly',
    alignSelf: 'stretch',
  },
  searchUsername: {
    fontSize: 18,
    fontWeight: '500',
  },
  commentUsername: {
    fontSize: 16,
    fontWeight: '500',
  },
  name: {
    fontSize: 16,
    color: '#333',
  },
});

export default ProfilePreview;
