import React, {useEffect, useState, useContext} from 'react';
import {ProfilePreviewType, ScreenType} 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 {PROFILE_PHOTO_THUMBNAIL_ENDPOINT} from '../../constants';
import {UserType, PreviewType} from '../../types';
import {isUserBlocked, loadAvatar} from '../../services';
import {useSelector, useDispatch, useStore} from 'react-redux';
import {RootState} from '../../store/rootreducer';
import {logout} from '../../store/actions';
import {fetchUserX, userXInStore} from '../../utils';
import {SearchResultsBackground} from '../search';
import NavigationBar from 'src/routes/tabs';

const NO_USER: UserType = {
  userId: '',
  username: '',
};

/**
 * This component returns user's profile picture friended 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.)
 * Finally, We navigate to Profile.
 */

interface ProfilePreviewProps extends ViewProps {
  profilePreview: ProfilePreviewType;
  previewType: PreviewType;
  screenType: ScreenType;
}

const ProfilePreview: React.FC<ProfilePreviewProps> = ({
  profilePreview: {username, first_name, last_name, id},
  previewType,
  screenType,
}) => {
  const navigation = useNavigation();
  const {user: loggedInUser} = useSelector((state: RootState) => state.user);
  const [avatarURI, setAvatarURI] = useState<string | null>(null);
  const [user, setUser] = useState<UserType>(NO_USER);
  const dispatch = useDispatch();
  useEffect(() => {
    let mounted = true;
    const loadAvatarImage = async () => {
      const response = await loadAvatar(id, true);
      if (mounted) {
        setAvatarURI(response);
      }
    };
    loadAvatarImage();
    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) {
      dispatch(logout());
      return false;
    }
    return await isUserBlocked(userId, loggedInUser.userId, token);
  };

  const state: RootState = useStore().getState();

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

    try {
      if (previewType !== 'Comment') {
        //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;
        }
        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);
        }
      }

      const userXId =
        loggedInUser.username === user.username ? undefined : user.id;

      /**
       * Dispatch an event to Fetch the user details only if we're navigating to
       * a userX's profile.
       * If the user is already present in store, do not fetch again.
       * Finally, Navigate to profile of the user selected.
       */
      if (userXId && !userXInStore(state, screenType, user.id)) {
        await fetchUserX(
          dispatch,
          {userId: user.id, username: user.username},
          screenType,
        );
      }

      navigation.push('Profile', {
        userXId,
        screenType,
      });
    } catch (e) {
      console.log(e);
    }
  };

  var containerStyle,
    avatarStyle,
    nameContainerStyle,
    usernameToDisplay,
    usernameStyle,
    nameStyle;

  switch (previewType) {
    case 'Search' || 'Recent':
      containerStyle = styles.searchResultContainer;
      avatarStyle = styles.searchResultAvatar;
      nameContainerStyle = styles.searchResultNameContainer;
      usernameToDisplay = '@' + username;
      usernameStyle = styles.searchResultUsername;
      nameStyle = styles.searchResultName;
      break;
    case 'Discover Users':
      containerStyle = styles.discoverUsersContainer;
      avatarStyle = styles.discoverUsersAvatar;
      nameContainerStyle = styles.discoverUsersNameContainer;
      usernameToDisplay = '@' + username;
      usernameStyle = styles.discoverUsersUsername;
      nameStyle = styles.discoverUsersName;
      break;
    case 'Comment':
      containerStyle = styles.commentContainer;
      avatarStyle = styles.commentAvatar;
      nameContainerStyle = styles.commentNameContainer;
      usernameToDisplay = username;
      usernameStyle = styles.commentUsername;
      nameStyle = styles.commentName;
      break;
    case 'Friend':
      containerStyle = styles.friendContainer;
      avatarStyle = styles.friendAvatar;
      nameContainerStyle = styles.friendNameContainer;
      usernameToDisplay = '@' + username;
      usernameStyle = styles.friendUsername;
      nameStyle = styles.friendName;
      break;
    default:
      containerStyle = styles.searchResultContainer;
      avatarStyle = styles.searchResultAvatar;
      nameContainerStyle = styles.searchResultNameContainer;
      usernameToDisplay = '@' + username;
      usernameStyle = styles.searchResultUsername;
      nameStyle = styles.searchResultName;
  }
  return (
    <TouchableOpacity
      onPress={addToRecentlyStoredAndNavigateToProfile}
      style={containerStyle}>
      <Image
        style={avatarStyle}
        source={
          avatarURI
            ? {uri: avatarURI}
            : require('../../assets/images/avatar-placeholder.png')
        }
      />
      <View style={nameContainerStyle}>
        {(previewType === 'Search' || previewType === 'Recent') && (
          <>
            <Text style={usernameStyle}>{usernameToDisplay}</Text>
            <Text style={nameStyle}>{first_name.concat(' ', last_name)}</Text>
          </>
        )}
        {previewType === 'Comment' && (
          <Text style={usernameStyle}>{usernameToDisplay}</Text>
        )}
        {previewType === 'Discover Users' && (
          <>
            <Text style={usernameStyle}>{usernameToDisplay}</Text>
          </>
        )}
        {previewType === 'Friend' && (
          <>
            <Text style={usernameStyle}>{usernameToDisplay}</Text>
            <Text style={nameStyle}>{first_name.concat(' ', last_name)}</Text>
          </>
        )}
      </View>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  searchResultContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 10,
  },
  commentContainer: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  discoverUsersContainer: {
    alignItems: 'center',
    textAlign: 'center',
    width: '32%',
    marginVertical: 10,
    borderWidth: 1,
  },
  searchResultAvatar: {
    height: 60,
    width: 60,
    borderRadius: 30,
    marginRight: 15,
  },
  commentAvatar: {
    height: 40,
    width: 40,
    borderRadius: 20,
    marginRight: 15,
    marginTop: '2%',
  },
  discoverUsersAvatar: {
    height: 60,
    width: 60,
    borderRadius: 30,
  },
  searchResultNameContainer: {
    justifyContent: 'space-evenly',
    alignSelf: 'stretch',
  },
  commentNameContainer: {
    justifyContent: 'space-evenly',
    alignSelf: 'stretch',
  },
  discoverUsersNameContainer: {
    justifyContent: 'space-evenly',
    alignSelf: 'stretch',
    marginTop: 5,
  },
  searchResultUsername: {
    fontSize: 18,
    fontWeight: '500',
  },
  commentUsername: {
    fontSize: 16,
    fontWeight: '500',
  },
  discoverUsersUsername: {
    fontSize: 14,
    fontWeight: '400',
    color: 'white',
    textAlign: 'center',
  },
  searchResultName: {
    fontSize: 16,
    color: '#333',
  },
  commentName: {
    fontSize: 16,
    color: '#333',
  },
  discoverUsersName: {
    fontSize: 16,
    fontWeight: '700',
    color: 'white',
    textAlign: 'center',
  },
  friendContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    marginVertical: 10,
  },
  friendAvatar: {
    height: 42,
    width: 42,
    marginRight: 15,
    borderRadius: 20,
  },
  friendNameContainer: {
    justifyContent: 'space-evenly',
    alignSelf: 'stretch',
  },
  friendUsername: {
    fontSize: 14,
    fontWeight: '700',
    color: '#3C3C3C',
    letterSpacing: 0.6,
  },
  friendName: {
    fontSize: 12,
    fontWeight: '500',
    color: '#6C6C6C',
    letterSpacing: 0.5,
  },
});

export default ProfilePreview;
