import React, { useState, useEffect, useRef } from 'react';
import { View, ActivityIndicator, TouchableOpacity } from 'react-native';
import { ResizeMode, Video } from 'expo-av';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import * as FileSystem from 'expo-file-system';
import { Colors } from 'src/theme';
import { CACHED_ATTACHMENTS_DIR } from 'src/constants/constants';
import { API_HOST } from 'src/constants';

const RenderMessageVideo = ({
  props,
  token,
  currentUserId,
  onLongPress
}: {
  props: any;
  token: string;
  currentUserId: number;
  onLongPress: (currentMessage: any, props: any) => any;
}) => {
  const { currentMessage } = props;

  if (!currentMessage?.video) return null;
  const leftMessage = currentMessage?.user?._id !== currentUserId;

  const videoRef = useRef<Video>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [isBuffering, setIsBuffering] = useState(true);
  const [videoUri, setVideoUri] = useState<string | null>(null);
  const [isVideoLoaded, setIsVideoLoaded] = useState(false);
  const [retryCount, setRetryCount] = useState(0);
  const MAX_RETRY = 3;

  const downloadVideo = async (videoUrl: string) => {
    if (!videoUrl.startsWith('https')) {
      setVideoUri(videoUrl);
      setIsVideoLoaded(true);
      return videoUrl;
    }

    try {
      const dirExist = await FileSystem.getInfoAsync(CACHED_ATTACHMENTS_DIR);
      if (!dirExist.exists) {
        await FileSystem.makeDirectoryAsync(CACHED_ATTACHMENTS_DIR, { intermediates: true });
      }

      const videoPath = `${CACHED_ATTACHMENTS_DIR}${currentMessage.attachment.filename}`;

      const videoExists = await FileSystem.getInfoAsync(videoPath);
      if (videoExists.exists) {
        if (videoExists.size < 1024) {
          await FileSystem.deleteAsync(videoPath, { idempotent: true });
        } else {
          try {
            await FileSystem.readAsStringAsync(videoPath, {
              encoding: FileSystem.EncodingType.Base64
            });
            setVideoUri(videoPath);
            setIsVideoLoaded(true);
            return videoPath;
          } catch (e) {
            await FileSystem.deleteAsync(videoPath, { idempotent: true });
          }
        }
      }

      const downloadResult = await FileSystem.downloadAsync(videoUrl, videoPath, {
        headers: {
          Nmtoken: token
        }
      });

      setVideoUri(downloadResult.uri);
      setIsVideoLoaded(true);

      return downloadResult.uri;
    } catch (error) {
      console.error('Error downloading video:', error);
      return null;
    }
  };

  useEffect(() => {
    const loadVideo = async () => {
      if (currentMessage?.video && !currentMessage?.isSending) {
        await downloadVideo(currentMessage.video);
      }
    };

    loadVideo();
  }, [currentMessage.video, currentMessage.isSending]);

  const handlePlaybackStatusUpdate = (playbackStatus: any) => {
    if (!playbackStatus.isLoaded) {
      setIsPlaying(false);
      setIsBuffering(false);
      return;
    }

    setIsPlaying(playbackStatus.isPlaying);
    setIsBuffering(playbackStatus.isBuffering ?? false);
  };

  const handlePlayPress = async () => {
    if (videoRef.current && isVideoLoaded) {
      await videoRef.current.presentFullscreenPlayer();
      await videoRef.current.playAsync();
    }
  };

  return (
    <View
      style={{
        width: 200,
        height: 200,
        padding: 6,
        borderRadius: 10
      }}
    >
      {videoUri ? (
        <Video
          ref={videoRef}
          source={{ uri: videoUri }}
          style={{ flex: 1, borderRadius: 10 }}
          resizeMode={ResizeMode.CONTAIN}
          useNativeControls
          isMuted={false}
          volume={1.0}
          shouldCorrectPitch
          onPlaybackStatusUpdate={handlePlaybackStatusUpdate}
          posterStyle={{ resizeMode: 'cover', width: '100%', height: '100%' }}
          usePoster={true}
          posterSource={{ uri: API_HOST + currentMessage.attachment.attachment_small_url }}
          onError={async () => {
            if (retryCount >= MAX_RETRY) {
              return;
            }

            if (videoUri) {
              await FileSystem.deleteAsync(videoUri, { idempotent: true });

              const newUri = await downloadVideo(currentMessage.video);
              if (newUri) {
                setVideoUri(newUri);
                setRetryCount(retryCount + 1);
              }
            }
          }}
        />
      ) : null}

      {isBuffering && (
        <View
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            alignItems: 'center',
            justifyContent: 'center'
          }}
        >
          <ActivityIndicator
            size="large"
            color={leftMessage ? Colors.DARK_BLUE : Colors.FILL_LIGHT}
          />
        </View>
      )}

      {!isPlaying && !isBuffering && videoUri && (
        <TouchableOpacity
          style={{
            position: 'absolute',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            alignItems: 'center',
            justifyContent: 'center'
          }}
          onPress={handlePlayPress}
          onLongPress={() => onLongPress(currentMessage, props)}
        >
          <View style={{ backgroundColor: 'rgba(15, 63, 79, 0.4)', borderRadius: 50 }}>
            <MaterialCommunityIcons name="play" size={60} color={Colors.WHITE} />
          </View>
        </TouchableOpacity>
      )}
    </View>
  );
};

export default RenderMessageVideo;
