import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {Image, StyleSheet, Text, View} from 'react-native';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
import {useDispatch, useStore} from 'react-redux';
import {loadImageFromURL, loadMomentThumbnail} from '../../services';
import {
  acceptFriendRequest,
  declineFriendRequest,
  loadUserNotifications,
  updateUserXFriends,
} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {MomentType, NotificationType, ScreenType} from '../../types';
import {fetchUserX, SCREEN_HEIGHT, userXInStore} from '../../utils';
import AcceptDeclineButtons from '../common/AcceptDeclineButtons';

interface NotificationProps {
  item: NotificationType;
  screenType: ScreenType;
  moments: MomentType[];
}

const Notification: React.FC<NotificationProps> = (props) => {
  const {
    item: {
      actor: {id, username, first_name, last_name, thumbnail_url},
      verbage,
      notification_type,
      notification_object,
      unread,
    },
    screenType,
    moments: loggedInUserMoments,
  } = props;

  const navigation = useNavigation();
  const state: RootState = useStore().getState();
  const dispatch = useDispatch();

  const [avatar, setAvatar] = useState<string | undefined>(undefined);
  const [momentURI, setMomentURI] = useState<string | undefined>(undefined);
  const backgroundColor = unread ? '#DCF1F1' : 'rgba(0,0,0,0)';

  useEffect(() => {
    (async () => {
      const response = await loadImageFromURL(thumbnail_url);
      if (response) {
        setAvatar(response);
      }
    })();
  }, []);

  useEffect(() => {
    let mounted = true;
    const loadMomentImage = async (moment_id: string) => {
      const response = await loadMomentThumbnail(moment_id);
      if (mounted && response) {
        setMomentURI(response);
      }
    };
    if (notification_type === 'CMT' && notification_object) {
      loadMomentImage(notification_object.moment_id);
      return () => {
        mounted = false;
      };
    }
  }, [id, notification_object, notification_type]);

  const onNotificationTap = async () => {
    switch (notification_type) {
      case 'FRD_ACPT':
      case 'FRD_REQ':
        if (!userXInStore(state, screenType, id)) {
          await fetchUserX(
            dispatch,
            {userId: id, username: username},
            screenType,
          );
        }
        navigation.push('Profile', {
          userXId: id,
          screenType,
        });
        break;
      case 'CMT':
        // find the moment we need to display
        const moment = loggedInUserMoments?.find(
          (m) => m.moment_id === notification_object?.moment_id,
        );
        if (moment) {
          navigation.push('IndividualMoment', {
            moment,
            userXId: undefined, // we're only viewing our own moment here
            screenType,
          });
          setTimeout(() => {
            navigation.push('MomentCommentsScreen', {
              moment_id: moment.moment_id,
              screenType,
            });
          }, 500);
        }
        break;
      default:
        break;
    }
  };

  const handleAcceptRequest = async () => {
    await dispatch(acceptFriendRequest({id, username, first_name, last_name}));
    await dispatch(updateUserXFriends(id, state));
    dispatch(loadUserNotifications());
  };

  const handleDeclineFriendRequest = async () => {
    await dispatch(declineFriendRequest(id));
    dispatch(loadUserNotifications());
  };

  return (
    <>
      <TouchableWithoutFeedback
        style={[styles.container, {backgroundColor}]}
        onPress={onNotificationTap}>
        <View style={styles.avatarContainer}>
          <Image
            style={styles.avatar}
            source={
              avatar
                ? {uri: avatar, cache: 'only-if-cached'}
                : require('../../assets/images/avatar-placeholder.png')
            }
          />
        </View>
        <View style={styles.contentContainer}>
          <Text style={styles.actorName}>
            {first_name} {last_name}
          </Text>
          <Text>{verbage}</Text>
        </View>
        {notification_type === 'FRD_REQ' && (
          <View style={styles.buttonsContainer}>
            <AcceptDeclineButtons
              requester={{id, username, first_name, last_name}}
              onAccept={handleAcceptRequest}
              onReject={handleDeclineFriendRequest}
            />
          </View>
        )}
        {notification_type === 'CMT' && notification_object && (
          <Image style={styles.moment} source={{uri: momentURI}} />
        )}
      </TouchableWithoutFeedback>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    height: SCREEN_HEIGHT / 10,
    flex: 1,
    alignItems: 'center',
  },
  avatarContainer: {
    marginLeft: '8%',
    flex: 1,
    justifyContent: 'center',
  },
  avatar: {
    height: 42,
    width: 42,
    borderRadius: 20,
  },
  contentContainer: {
    flex: 5,
    marginLeft: '5%',
    height: '80%',
    flexDirection: 'column',
    justifyContent: 'space-around',
    marginRight: '15%',
  },
  actorName: {
    fontSize: 15,
    fontWeight: '700',
  },
  moment: {
    position: 'absolute',
    height: 42,
    width: 42,
    right: '5%',
  },
  buttonsContainer: {},
});

export default Notification;
