import React, { useEffect, useState } from "react";
import {
  StyleSheet,
  View,
  Image,
  Text,
  BackHandler,
  Alert,

} from "react-native";
import { translate } from "react-native-digitcamera/src/common/localize/i18n";
import { ProgressBar } from "react-native-paper";
import reactotron from "reactotron-react-native";
import Header from "./Header";
import Orientation from "../../../react-native-orientation";
import { useSelector } from "react-redux";
import {
  UELogEvent,
  UELogMessage,
} from "../common/libEventLog/UserExperior/LibUserExperior";
import Database from "../../../../Components/common/DAsyncStorage";

import NetInfo from "@react-native-community/netinfo";
import { offlinePIDataToRealm } from "react-native-digitcamera/src/Screens/OfflineFlow/CommonFunc";
import MCIcon from "react-native-vector-icons/MaterialCommunityIcons"
import { useMemo } from "react";


var totalImages = 0;
var docProgress = 0;
var uploadedInterval;
const VideoPIProgress = ({ navigation, route }) => {
  const [, updateState] = React.useState();
  const forceUpdate = React.useCallback(() => updateState({}), []);
  const [isUploadFailed, setIsUploadFailed] = useState(false);
  const [progress, setProgress] = useState("0");
  const [isInternetConnected, setIsInternetConnected] = useState(true);
  const [uploadTimeAndSpeed, setUploadTimeAndSpeed] = useState({
    uploadSpeed: 0,
    secondsRemaining: 0
  })

  const internetChangeListener = useMemo(async () => {
    var AppLoginStatus = await Database.get("AppLoginStatus");
    if (!isInternetConnected) {
      uploadFailedAlert(AppLoginStatus)
    }
  }, [isInternetConnected]);

  useEffect(() => {
    Orientation.lockToPortrait();
    const getUploadedData = async () => {
      var PIVideoCompleteStatus = await Database.get("PIVideoCompleteStatus");
      var completedCount = PIVideoCompleteStatus?.completePercentage;
      let uploadInfo = PIVideoCompleteStatus?.uploadInfo;
      if (!isInternetConnected) {
        uploadInfo = { uploadSpeed: 0, secondsRemaining: 0 };
      }
      console.log("($) VideoPIProgress . uploadInfo - ", uploadInfo)

      setUploadTimeAndSpeed(uploadInfo)


      if (
        completedCount == undefined ||
        completedCount == "NaN" ||
        completedCount == null
      ) {
        completedCount = 0;
      }
      console.log(
        "*** VideoPIProgress getUploadedDaata completedCount: " + completedCount
      );
      setProgress(completedCount);
      docProgress = completedCount;
      // UELogEvent("VideoPIProgress. useEffect, completedCount, ", {
      //   "completedCount": JSON.stringify(completedCount)
      // })
      const mediaStatusObjs = await Database.get("PIMediaStatus");
      // UELogEvent("VideoPIProgress.  useEffect, mediaStatusObj, ", {
      //   "mediaStatusObj": JSON.stringify(mediaStatusObjs)
      // })
      totalImages = mediaStatusObjs?.length;
      // UELogEvent("VideoPIProgress.  useEffect, totalImage, ", {
      //   "totalImages": JSON.stringify(totalImages)
      // })
      var uploadedImages = [];
      var failedUploads = [];


      /* 
       Commented this, because push method adds element to array instead of returning the exactly uploaded/failed array
       push can then put duplicates elements into the array if any asynchronous behaviour happens
       this will directly increase the size of elements which are either uploaded or failed
       I'm using filter method which returns only/fixed elements those are uploaded/failed. from fixed mediaStatusObjs 
       */

      // mediaStatusObjs.map((item, index) => {
      //   if (item?.status === "uploaded") {
      //     uploadedImages.push(item);
      //   }
      //   if (item?.status === "failed") {
      //     console.log("Failed Image >>> videoPIProgress.js", item);
      //     failedUploads.push(item);
      //   }
      // });

      uploadedImages = mediaStatusObjs?.filter(item => item?.status === "uploaded")
      failedUploads = mediaStatusObjs?.filter(item => item?.status === "failed")

      console.log(
        "**** Progress totalImages: " +
        totalImages +
        " -> uploadedImages: " +
        uploadedImages?.length +
        "  : failedUploads: " +
        failedUploads?.length
      );
      if (failedUploads?.length + uploadedImages?.length == totalImages) {
        if (failedUploads?.length > 0) {
          // clearInterval(uploadedInterval);
          setIsUploadFailed(true);
          navigateTOthankYou(true);
        } else {
          // clearInterval(uploadedInterval);
          navigateTOthankYou(false);
        }
      }

      // UELogEvent("VideoPIProgress.  useEffect, uploadedImages length ", {
      //   "uploadedImages": JSON.stringify(uploadedImages.length)
      // })
      console.log("**** Progress uploadedImages: " + uploadedImages.length);
    };
    uploadedInterval = setInterval(() => {
      getUploadedData();
    }, 1000);

    let unsubscribe = navigation.addListener("focus", () => {
      Orientation.lockToPortrait();
    });

    var unsubscribeNetInfo = NetInfo.addEventListener(async (state) => {
      console.log("In NetInfo withQuote");
      if (state.isInternetReachable) {
        setIsInternetConnected(true);
      } else {
        setIsInternetConnected(false);
      }
    });

    const backHandler = BackHandler.addEventListener(
      "hardwareBackPress",
      () => {
        return true;
      }
    );

    return () => {
      backHandler.remove();
      unsubscribe();
      unsubscribeNetInfo && unsubscribeNetInfo()
      if (uploadedInterval) {
        clearInterval(uploadedInterval);
      }
    };
  }, []);

  const uploadFailedAlert = (AppLoginStatus) => {
    clearInterval(uploadedInterval);
    Alert.alert("You are offline!", "We will try to upload images ones we get good internet", [
      {
        text: "OK",
        onPress: () => {
          // delete mediastatus data from realm
          try {
            console.log("called if no internet >>>>>>>>        >>>>>>>>>>>>         >>>>>>>>>");
            offlinePIDataToRealm(true)
          }
          catch (e) {
            console.log("(&)=> VideoPIProgress.js, Error in deleting PIMediaStatus from realms =>", e);
          }
          if (AppLoginStatus[0]?.userType === "OEMDealer") {
            route.params.props.navigation.navigate("VehicleInspection");
          }
          else {
            navigation.navigate("WithQuote");
          }
        }
      }
    ])
  }

  const navigateTOthankYou = async (isUploadFailed) => {
    /*
     * Checking if any one of the upload fails
     * If fails redirecting user to Withquote.js
     *
     */
    var AppLoginStatus = await Database.get("AppLoginStatus");
    if (false) {
      clearInterval(uploadedInterval);
      // clearInterval(uploadedInterval)
      Alert.alert("Oops!", "Something went wrong, please retry again", [
        {
          text: "OK",
          onPress: async () => {
            // delete mediastatus data from realm
            try {
              console.log(
                "($)=> VideoPIProgress.js Deleting PIMediaStatus from realm"
              );
              offlinePIDataToRealm(true)
            } catch (e) {
              console.log(
                "(&)=> VideoPIProgress.js, Error in deleting PIMediaStatus from realms =>",
                e
              );
            }
            if (AppLoginStatus?.userType === "OEMDealer") {
              route.params.props.navigation.navigate("VehicleInspection");
            } else {
              navigation.navigate("WithQuote");
            }
          },
        },
      ]);
    }

    if (isInternetConnected) {
      console.log("*** VideoPIProgress.js docProgress: " + docProgress);
      if (docProgress >= 100) {
        clearInterval(uploadedInterval);
        var PIVechicleData = await Database.get("PIVechicleData");
        var activityId = PIVechicleData?.activityId;
        // docProgress = 0;
        // totalImages = 0;  
        navigation.replace("ThankYou", { activityId: activityId });
      }
    }
  };

  const getEstimatedSeconds = (sec) => {
    if (sec === undefined || sec === null) {
      return 0;
    }
    return getTimeInMinAndSec(sec)
  }

  const getSpeedInMbps = (speed) => {
    if (speed === undefined || speed === null) {
      return `0 Mbps`;
    }
    return `${(speed / 1024).toFixed(3)} Mbps`;
  }

  const getTimeInMinAndSec = (sec) => {
    if (sec === undefined || sec === null) {
      return `0 sec`;
    }
    const min = sec / 60;
    const remSec = sec % 60;
    return `${Math.floor(min)} min ${Math.floor(remSec)} sec`;
  }

  return (
    <View style={styles.main}>
      <Header
        customTitle=""
        hideArrowBackButton={true}
        onlanguagechange={() => {
          forceUpdate();
        }}
        onbackPress={() => {
          navigation.goBack();
        }}
        shiftTitleToLeft={true}
      />
      {/* GIF view */}
      <View style={styles.gifView}>
        <Image
          source={{
            uri: "https://d2h44aw7l5xdvz.cloudfront.net/assets/gif/cycle.gif",
            cache: 'only-if-cached'
          }}
          style={{
            width: "100%",
            resizeMode: "contain",
            aspectRatio: 1
          }}
        />
      </View>
      {/* Progress View */}
      <View style={styles.progressView}>
        <Text style={styles.boldText}>{"Uploading in progress"}</Text>
        <ProgressBar
          progress={docProgress * 0.01}
          color={"#FFBB00"}
          style={{ height: 12, borderRadius: 6, backgroundColor: "#F5F5F5" }}
        />
        <Text style={styles.doneText}>
          <Text style={{ fontWeight: "800" }}>{Math.floor(docProgress)}%</Text> Done
        </Text>
        <Text style={styles.subText}>
          {
            "Please wait while the upload completes"
          }
        </Text>
        {isInternetConnected && <View style={{ marginVertical: 30, flexDirection: "row", justifyContent: "space-between", }}>
          <View style={styles.iconContainer}>
            <MCIcon name="clock-outline" size={12} color="black" style={{ marginRight: 4 }} />
            <Text style={styles.iconLabel}>
              Estimated Time Left: {getTimeInMinAndSec(uploadTimeAndSpeed?.secondsRemaining)}
            </Text>
          </View>

          <View style={styles.iconContainer}>
            <MCIcon name="speedometer" size={12} color="black" style={{ marginRight: 4 }} />
            <Text style={styles.iconLabel}>
              Speed: {getSpeedInMbps(uploadTimeAndSpeed?.uploadSpeed)}
            </Text>
          </View>
        </View>
        }
      </View>
    </View>
  );
};
const styles = StyleSheet.create({
  main: {
    flex: 1,
    backgroundColor: "#FFFFFF",
  },
  gifView: {
    flex: 0.4,
    justifyContent: "center",
    marginBottom: 40,
    marginLeft: 24,
    marginRight: 24,
    alignItems: "center",
  },
  progressView: {
    flex: 0.4,
    marginLeft: 24,
    marginRight: 24,
  },
  processingText: {
    fontFamily: "Muli-Bold",
    fontSize: 20,
    alignSelf: "center",
    marginBottom: 15,
  },
  boldText: {
    fontFamily: "Muli-ExtraBold",
    fontSize: 20,
    alignSelf: "center",
    marginBottom: 24,
  },
  doneText: {
    fontFamily: "Muli-Regular",
    fontSize: 14,
    marginTop: 12,
    alignSelf: "center",
  },
  subText: {
    fontFamily: "Muli-ExtraBold",
    fontSize: 14,
    marginTop: 16,
    alignSelf: "center",
  },
  buttonView: {
    flex: 0.1,
    justifyContent: "center",
  },
  iconContainer: {
    flexDirection: "row",
    justifyContent: 'center',
    alignItems: "center"
  },
  iconLabel:
  {
    fontSize: 10,
    fontFamily: "Muli-Regular"
  }

});
export default VideoPIProgress;
