import React, { useMemo } from 'react';
import { StyleSheet, View } from 'react-native';
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import { AndroidScoped } from 'react-native-file-access';
import { useSelector } from 'react-redux';
import Video from 'react-native-video';
import { MEME_TYPE, Meme } from '../../database';
import { RootState } from '../../state';
import { AnimatedImage, LoadingView, MemeFail } from '../../components';
import { useMemeDimensions } from '../../hooks';

const memeViewItemStyles = StyleSheet.create({
  view: {
    justifyContent: 'center',
    alignItems: 'center',
  },
});

const MemeViewItem = ({ meme }: { meme: Meme }) => {
  const { height, width } = useSafeAreaFrame();
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  const storageUri = useSelector(
    (state: RootState) => state.settings.storageUri,
  )!;

  const uri = AndroidScoped.appendPath(storageUri, meme.filename);

  const { dimensions, loading, error } = useMemeDimensions(uri, meme.mimeType);

  const mediaComponent = useMemo(() => {
    if (!dimensions) return <></>;

    const dimensionStyles =
      dimensions.aspectRatio > width / (height - 128)
        ? {
            width,
            height: width / (dimensions.width / dimensions.height),
          }
        : {
            width: (height - 128) * (dimensions.width / dimensions.height),
            height: height - 128,
          };

    switch (meme.memeType) {
      case MEME_TYPE.IMAGE:
      case MEME_TYPE.GIF: {
        return <AnimatedImage source={{ uri }} style={dimensionStyles} />;
      }
      default: {
        return (
          <Video source={{ uri }} style={dimensionStyles} paused controls />
        );
      }
    }
  }, [dimensions, height, meme.memeType, uri, width]);

  if (!error && (loading || !dimensions)) {
    return <LoadingView style={{ width, height }} />;
  }

  return (
    <View style={[{ width, height }, memeViewItemStyles.view]}>
      {error || !dimensions ? (
        <MemeFail
          style={{
            width: Math.min(width, height - 128),
            height: Math.min(width, height - 128),
          }}
          iconSize={50}
        />
      ) : (
        mediaComponent
      )}
    </View>
  );
};

export default MemeViewItem;
