import {RouteProp} from '@react-navigation/core';
import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useRef, useState} from 'react';
import {Image, StyleSheet, TouchableWithoutFeedback, View} from 'react-native';
import {Button} from 'react-native-elements';
import Video from 'react-native-video';
import {MainStackParams} from 'src/routes';
import {
  CaptionScreenHeader,
  MomentTags,
  SearchBackground,
} from '../../components';
import {TagFriendsFooter} from '../../components/moments';
import {TAGG_LIGHT_BLUE_2} from '../../constants';
import {MomentTagType} from '../../types';
import {SCREEN_WIDTH, StatusBarHeight} from '../../utils';

type TagFriendsScreenRouteProps = RouteProp<
  MainStackParams,
  'TagFriendsScreen'
>;
interface TagFriendsScreenProps {
  route: TagFriendsScreenRouteProps;
}
const TagFriendsScreen: React.FC<TagFriendsScreenProps> = ({route}) => {
  const {media, selectedTags} = route.params;
  const navigation = useNavigation();
  const imageRef = useRef(null);
  const [tags, setTags] = useState<MomentTagType[]>([]);
  const [imageWidth, setImageWidth] = useState<number>(0);
  const [imageHeight, setImageHeight] = useState<number>(0);

  /*
   * Update list of tagged users from route params
   */
  useEffect(() => {
    setTags(selectedTags ? selectedTags : []);
  }, [selectedTags]);

  /*
   * Navigate back to Tag Users Screen, send selected users
   */
  const handleDone = () => {
    navigation.navigate('CaptionScreen', {
      ...route.params,
      selectedTags: tags,
    });
  };

  const setMediaDimensions = (width: number, height: number) => {
    const imageAspectRatio = width / height;

    // aspectRatio: >= 1 [Landscape] [1:1]
    if (imageAspectRatio >= 1) {
      setImageWidth(SCREEN_WIDTH);
      setImageHeight(SCREEN_WIDTH / imageAspectRatio);
    }
    // aspectRatio: < 1 [Portrait]
    if (imageAspectRatio < 1) {
      setImageHeight(SCREEN_WIDTH);
      setImageWidth(SCREEN_WIDTH * imageAspectRatio);
    }
  };

  /*
   * Calculating image width and height with respect to it's enclosing view's dimensions. Only works for images.
   */
  useEffect(() => {
    if (imageRef && imageRef.current && !media.isVideo) {
      Image.getSize(
        media.uri,
        (w, h) => {
          setMediaDimensions(w, h);
        },
        (err) => console.log(err),
      );
    }
  }, []);

  return (
    <SearchBackground>
      <View style={styles.contentContainer}>
        <View style={styles.buttonsContainer}>
          <Button
            title="Cancel"
            buttonStyle={styles.button}
            onPress={() => navigation.goBack()}
          />
          <Button
            title="Done"
            titleStyle={styles.shareButtonTitle}
            buttonStyle={styles.button}
            onPress={handleDone}
          />
        </View>
        <CaptionScreenHeader
          style={styles.header}
          title={'Tap on photo to tag friends!'}
        />
        <TouchableWithoutFeedback
          onPress={() =>
            navigation.navigate('TagSelectionScreen', {
              selectedTags: tags,
            })
          }>
          {media.isVideo ? (
            <View
              style={{
                width: imageWidth,
                height: imageHeight,
                marginVertical: (SCREEN_WIDTH - imageHeight) / 2,
                marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2,
              }}
              ref={imageRef}>
              <Video
                style={{
                  width: imageWidth,
                  height: imageHeight,
                }}
                source={{uri: media.uri}}
                repeat={true}
                onLoad={(response) => {
                  const {width, height, orientation} = response.naturalSize;
                  // portrait will flip width and height
                  if (orientation === 'portrait') {
                    setMediaDimensions(height, width);
                  } else {
                    setMediaDimensions(width, height);
                  }
                }}
              />
            </View>
          ) : (
            <Image
              ref={imageRef}
              style={{
                width: imageWidth,
                height: imageHeight,
                marginVertical: (SCREEN_WIDTH - imageHeight) / 2,
                marginHorizontal: (SCREEN_WIDTH - imageWidth) / 2,
              }}
              source={{uri: media.uri}}
            />
          )}
        </TouchableWithoutFeedback>
        {tags.length !== 0 && (
          <MomentTags
            tags={tags}
            setTags={setTags}
            editing={true}
            imageRef={imageRef}
            deleteFromList={(user) =>
              setTags(tags.filter((tag) => tag.user.id !== user.id))
            }
          />
        )}
        <View style={styles.footerContainer}>
          <TagFriendsFooter tags={tags} setTags={setTags} />
        </View>
      </View>
    </SearchBackground>
  );
};

const styles = StyleSheet.create({
  contentContainer: {
    paddingTop: StatusBarHeight,
  },
  buttonsContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginLeft: '5%',
    marginRight: '5%',
  },
  button: {
    backgroundColor: 'transparent',
  },
  shareButtonTitle: {
    fontWeight: 'bold',
    color: TAGG_LIGHT_BLUE_2,
  },
  header: {
    marginVertical: 20,
  },
  footerContainer: {
    marginHorizontal: '5%',
    marginTop: '3%',
  },
});

export default TagFriendsScreen;
