import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {Alert, Image, StyleSheet, Text, View} from 'react-native';
import {TouchableOpacity} from 'react-native-gesture-handler';
import {useDispatch, useStore} from 'react-redux';
import {ERROR_UNABLE_TO_VIEW_PROFILE} from '../../constants/strings';
import {loadImageFromURL} from '../../services';
import {RootState} from '../../store/rootReducer';
import {
  ProfilePreviewType,
  ScreenType,
  UserType,
  CategoryPreviewType,
} from '../../types';
import {normalize, SCREEN_WIDTH} from '../../utils';
import {
  addUserToRecentlyViewed,
  checkIfUserIsBlocked,
  defaultUserProfile,
  fetchUserX,
  userXInStore,
  addCategoryToRecentlySearched,
} from '../../utils/users';

interface SearchResults {
  type: 'badges' | 'categories' | 'users';
  profileData: ProfilePreviewType;
  loggedInUser: UserType;
}

const SearchResultsCell: React.FC<SearchResults> = ({
  type,
  profileData: {
    id,
    name,
    username,
    first_name,
    last_name,
    thumbnail_url,
    category,
  },
  loggedInUser,
}) => {
  const [avatar, setAvatar] = useState<string | undefined>(undefined);
  useEffect(() => {
    (async () => {
      if (thumbnail_url !== undefined) {
        try {
          const response = await loadImageFromURL(thumbnail_url);
          if (response) {
            setAvatar(response);
          }
        } catch (error) {
          console.log('Error while downloading ', error);
          throw error;
        }
      }
    })();
  }, [thumbnail_url]);

  const dispatch = useDispatch();
  const state: RootState = useStore().getState();
  const navigation = useNavigation();
  const addToRecentlyStoredAndNavigateToProfile = async () => {
    try {
      //If the logged in user is blocked by the user being viewed, do not proceed.
      const isUserBlocked = await checkIfUserIsBlocked(
        id,
        dispatch,
        loggedInUser,
      );
      if (isUserBlocked) {
        Alert.alert(ERROR_UNABLE_TO_VIEW_PROFILE);
        return;
      }

      addUserToRecentlyViewed({
        id,
        first_name,
        last_name,
        thumbnail_url,
        username,
      });

      const userXId = loggedInUser.username === username ? undefined : 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.Search, id)) {
        await fetchUserX(
          dispatch,
          {userId: id, username: username},
          ScreenType.Search,
        );
      }

      navigation.navigate('Profile', {
        userXId,
        screenType: ScreenType.Search,
      });
    } catch (e) {
      console.log(e);
    }
  };

  /*
   * Save selected category in recently-searched categories and navigate to its Discover screen.
   */
  const onPressCategory = async () => {
    const categoryObj: CategoryPreviewType = {name, category};
    addCategoryToRecentlySearched(categoryObj);
    navigation.navigate('DiscoverUsers', {
      type,
      searchCategory: {id, name},
    });
  };

  const userCell = () => {
    return (
      <TouchableOpacity
        onPress={addToRecentlyStoredAndNavigateToProfile}
        style={styles.cellContainer}>
        <Image
          defaultSource={defaultUserProfile()}
          source={{uri: avatar}}
          style={styles.imageContainer}
        />
        <View style={[styles.initialTextContainer, styles.multiText]}>
          <Text style={styles.initialTextStyle}>{`@${username}`}</Text>
          <Text style={styles.secondaryTextStyle}>
            {first_name + ' ' + last_name}
          </Text>
        </View>
      </TouchableOpacity>
    );
  };

  const searchIcon = () => {
    return require('../../assets/images/search.png');
  };

  const universityIcon = () => {
    return require('../../assets/images/bwbadges.png');
  };

  const categoryCell = () => {
    return (
      <TouchableOpacity style={styles.cellContainer} onPress={onPressCategory}>
        <View style={[styles.imageContainer, styles.categoryBackground]}>
          <Image
            resizeMode="contain"
            source={category === 'Brown' ? universityIcon() : searchIcon()}
            style={styles.categoryImage}
          />
        </View>
        <View style={styles.initialTextContainer}>
          <Text style={styles.initialTextStyle}>{name}</Text>
        </View>
      </TouchableOpacity>
    );
  };

  return name === undefined ? userCell() : categoryCell();
};

const styles = StyleSheet.create({
  cellContainer: {
    flexDirection: 'row',
    paddingHorizontal: 25,
    paddingVertical: 15,
    width: SCREEN_WIDTH,
  },
  imageContainer: {
    width: SCREEN_WIDTH * 0.112,
    height: SCREEN_WIDTH * 0.112,
    borderRadius: (SCREEN_WIDTH * 0.112) / 2,
  },
  categoryBackground: {
    backgroundColor: 'rgba(196, 196, 196, 0.45)',
    justifyContent: 'center',
    alignItems: 'center',
  },
  categoryImage: {
    width: '40%',
    height: '40%',
  },
  initialTextContainer: {
    marginLeft: SCREEN_WIDTH * 0.08,
    flexDirection: 'column',
    justifyContent: 'center',
  },
  initialTextStyle: {
    fontWeight: '500',
    fontSize: normalize(14),
  },
  secondaryTextStyle: {
    fontWeight: '500',
    fontSize: normalize(12),
    color: '#828282',
  },
  multiText: {justifyContent: 'space-between'},
});

export default SearchResultsCell;
