import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { View, Image, Text, TouchableOpacity } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import * as Progress from 'react-native-progress';

import { getImageUri, photoStyles, smallPhotoHeight, smallPhotoWidth } from '../../utils';
import { NAVIGATION_PAGES } from 'src/types';
import { styles } from '../../Components/styles';

import { API_HOST } from 'src/constants';
import ImageView from 'better-react-native-image-viewing';
import { EventPhotos } from '@api/events';
import { ImageSource } from 'expo-image';
import { Colors } from 'src/theme';

type Photo = {
  id: number;
  filetype: string;
  data: 0 | 1;
  preview: 0 | 1;
  uid: number;
  name: string;
  avatar: string | null;
  uri: string;
  isSending?: boolean;
};

export const PhotoItem = React.memo(
  ({ photos, eventId, photosLeft }: { photos: any; eventId: number; photosLeft: number }) => {
    const navigation = useNavigation();
    const [currentImageIndex, setCurrentImageIndex] = useState(0);
    const [isViewerVisible, setIsViewerVisible] = useState(false);
    const [fullImages, setFullImages] = useState<EventPhotos[]>([]);

    const openImageViewer = (index: number) => {
      setCurrentImageIndex(index);
      setIsViewerVisible(true);
    };

    useEffect(() => {
      setFullImages(
        photos
          .filter((p: EventPhotos) => p.data)
          .map((photo: Photo) => ({
            ...photo,
            uri: API_HOST + '/webapi/events/get-photo/' + eventId + '/' + photo.id
          }))
      );
    }, [photos]);

    const renderSpinner = (style: any) => (
      <View
        style={[
          style,
          {
            alignItems: 'center',
            justifyContent: 'center',
            backgroundColor: Colors.FILL_LIGHT
          }
        ]}
      >
        <Progress.CircleSnail
          borderWidth={0}
          color={Colors.DARK_BLUE}
          unfilledColor="rgba(0, 0, 0, 0.1)"
        />
      </View>
    );

    const renderPhotos = () => {
      const photosToShow = photos.filter((p: EventPhotos) => p.preview).slice(0, 3);
      const morePhotosCount = photos.length - 3 + photosLeft;

      if (photosToShow.length === 1) {
        return (
          <TouchableOpacity onPress={() => openImageViewer(0)}>
            {photosToShow[0].isSending ? (
              renderSpinner(photoStyles.onePhoto)
            ) : (
              <Image
                source={{
                  uri: getImageUri(
                    '/webapi/events/get-photo-preview/' + eventId + '/' + photosToShow[0].id
                  )
                }}
                style={photoStyles.onePhoto}
              />
            )}
          </TouchableOpacity>
        );
      } else if (photosToShow.length === 2) {
        return photosToShow.map((photo: Photo, index: number) => (
          <TouchableOpacity key={photo.id} onPress={() => openImageViewer(index)}>
            {photo?.isSending ? (
              renderSpinner({ ...photoStyles.twoPhotos, marginRight: index === 0 ? 8 : 0 })
            ) : (
              <Image
                source={{
                  uri: getImageUri(
                    '/webapi/events/get-photo-preview/' + eventId + '/' + photosToShow.id
                  )
                }}
                style={[photoStyles.twoPhotos, index === 0 && { marginRight: 8 }]}
              />
            )}
          </TouchableOpacity>
        ));
      } else {
        return (
          <View style={{ flexDirection: 'row' }}>
            <TouchableOpacity onPress={() => openImageViewer(0)}>
              {photosToShow[0].isSending ? (
                renderSpinner(photoStyles.bigPhoto)
              ) : (
                <Image
                  source={{
                    uri: getImageUri(
                      '/webapi/events/get-photo-preview/' + eventId + '/' + photosToShow[0].id
                    )
                  }}
                  style={photoStyles.bigPhoto}
                />
              )}
            </TouchableOpacity>

            <View style={styles.smallPhotoContainer}>
              <TouchableOpacity onPress={() => openImageViewer(1)}>
                {photosToShow[1].isSending ? (
                  renderSpinner(photoStyles.smallPhoto)
                ) : (
                  <Image
                    source={{
                      uri: getImageUri(
                        '/webapi/events/get-photo-preview/' + eventId + '/' + photosToShow[1].id
                      )
                    }}
                    style={photoStyles.smallPhoto}
                  />
                )}
              </TouchableOpacity>
              <TouchableOpacity onPress={() => openImageViewer(2)}>
                <Image
                  source={{
                    uri: getImageUri(
                      '/webapi/events/get-photo-preview/' + eventId + '/' + photosToShow[2].id
                    )
                  }}
                  style={[photoStyles.smallPhoto, { position: 'relative' }]}
                />
              </TouchableOpacity>
              {morePhotosCount > 0 && (
                <TouchableOpacity
                  onPress={() => handlePress()}
                  style={[
                    styles.morePhotosOverlay,
                    { width: smallPhotoWidth, height: smallPhotoHeight }
                  ]}
                >
                  <Text style={styles.morePhotosText}>+{morePhotosCount}</Text>
                </TouchableOpacity>
              )}
            </View>
          </View>
        );
      }
    };

    const photoViews = useMemo(() => renderPhotos(), [photos]);

    const handlePress = useCallback(() => {
      navigation.navigate(
        ...([
          NAVIGATION_PAGES.ALL_EVENT_PHOTOS,
          {
            data: photos,
            eventId,
            lastPhotoId: photos[photos.length - 1].id,
            photosCountLeft: photosLeft
          }
        ] as never)
      );
    }, [navigation, photos]);

    return (
      <View>
        {photoViews}
        <ImageView
          images={fullImages as ImageSource[]}
          keyExtractor={(imageSrc, index) => index.toString()}
          imageIndex={currentImageIndex}
          visible={isViewerVisible}
          onRequestClose={() => setIsViewerVisible(false)}
          swipeToCloseEnabled={false}
          backgroundColor={Colors.DARK_BLUE}
          FooterComponent={({ imageIndex }) => (
            <View style={styles.imageFooter}>
              <TouchableOpacity
                onPress={() => {
                  setIsViewerVisible(false);
                  navigation.navigate(
                    ...([
                      NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW,
                      { userId: fullImages[imageIndex].uid }
                    ] as never)
                  );
                }}
                disabled={!fullImages[imageIndex].uid}
                style={styles.imageOwner}
              >
                {fullImages[imageIndex].avatar ? (
                  <Image
                    source={{ uri: API_HOST + fullImages[imageIndex].avatar }}
                    style={{
                      width: 28,
                      height: 28,
                      borderRadius: 14
                    }}
                  />
                ) : null}
                <Text style={styles.imageOwnerText}>{fullImages[imageIndex].name}</Text>
              </TouchableOpacity>
            </View>
          )}
        />
      </View>
    );
  }
);
