import { SELFSURVEYSERVICE_DOCUMENT_URL } from "react-native-digitcamera/src/Api/ApiUrls";
import {
  UEEndTimer,
  UELogEvent,
  UEStartTimer,
} from "react-native-digitcamera/src/common/libEventLog/UserExperior/LibUserExperior";
import Database from "../../../../Components/common/DAsyncStorage";
import DeviceInfo from "react-native-device-info";
import { forwardRef, useEffect, useState } from "react";
import { Alert, Platform } from "react-native";
import { async } from "validate.js";
import RNFetchBlob from "rn-fetch-blob";
const { getImei } = require("react-native-imei");
const iOS = Platform.OS === "ios";

export async function UploadFile(
  mediaUri,
  DocumentImageName,
  ext,
  failedCallBack,
  uploadSuccess,
  uploadFailure
) {
  var MAC = "";
  var deviceName = "";
  var IP = "";
  var apiLevel = "";
  var IMEI = "";
  try {
    var file = "file://";
    const uri = iOS ? mediaUri.replace("file://", "") : file + mediaUri;
    console.log("*** UploadFile : " + DocumentImageName + " uri: " + uri);
    var PILocation = await Database.get("PILocation");
    var currentLatitude = PILocation?.lat;
    var currentLongitude = PILocation?.long;
    var PIVechicleData = await Database.get("PIVechicleData");
    var activityId = PIVechicleData?.activityId;
    var quoteNumber = PIVechicleData?.quoteNumber;
    var regNumber = PIVechicleData?.licensePlateNumber;
    var PIOdometerData = await Database.get("PIOdometerData");
    console.log(
      "********************************************************************* UploadFile : " +
        DocumentImageName +
        " activityId: " +
        activityId
    );

    console.log(
      "**** UploadFile PIOdometerData: " + JSON.stringify(PIOdometerData)
    );
    deviceName = await DeviceInfo.getDeviceName();
    console.log("*** UploadFile getDeviceName: " + deviceName);
    if (activityId == undefined || activityId.length == 0) {
      Alert.alert("Oops!", "Something went wrong, please retry again");
      if (failedCallBack !== undefined) {
        failedCallBack();
      }
    }

    MAC = await DeviceInfo.getMacAddress();
    console.log("*** UploadFile getMacAddress: " + MAC);
    IP = await DeviceInfo.getIpAddress();
    console.log("*** UploadFile getIpAddress: " + IP);

    apiLevel = await DeviceInfo.getApiLevel();
    console.log("*** UploadFile getApiLevel: " + apiLevel);
    if (!iOS) {
      if (apiLevel > 28) {
        IMEI = await DeviceInfo.getAndroidId();
      } else {
        const imeiList = await getImei();
        if (imeiList !== undefined) {
          IMEI = imeiList[0];
        }
      }
    }
    console.log("*** UploadFile getImei / getAndroidId: " + IMEI);

    const getFileSize = async (uri, imageName) => {
      /*
       * Using RNFetchBlob.fs.stat(uri) method which retrieves meta information
       * of the file of the *uri*
       * stats.size returns size of the file in bytes
       * the method, getFileSizeInMB converts the bytes into MB
       */
      try {
        const stats = await RNFetchBlob.fs.stat(uri);
        console.log(
          `Camera.js ${imageName} file size: `,
          stats?.size,
          `bytes, ${getFileSizeInMB(stats?.size)} mb`
        );
        UELogEvent(`Camera.js ${imageName} file size in bytes`, {
          "FileSize (bytes)": JSON.stringify(stats?.size),
          "FileSize (MegaBytes)": JSON.stringify(getFileSizeInMB(stats?.size)),
        });
      } catch (e) {
        console.log("Error in UploadFile, getFileSize", e);
      }
    };

    const getFileSizeInMB = (bytes) => {
      /* converts bytes to megabytes */
      return bytes * 0.000001;
    };

    // Calling getFileSize
    getFileSize(uri, DocumentImageName);

    UELogEvent("uploadImage is started", {
      uri: JSON.stringify(uri),
      documentName: JSON.stringify(DocumentImageName),
      ImageName: JSON.stringify(activityId + "_" + DocumentImageName + ext),
    });
    console.log("In Upload Uploading Image Name ", DocumentImageName);
    console.log("IMAGE NAME  ", activityId + "_" + DocumentImageName + ext);
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    console.log("IMAGE URI TO BE UPLOADED > > >   ", uri);

    const addMediaStatusObj = (oldStatus, myObj) => {
      console.log("0 " + myObj);
      var newObj;
      if (oldStatus == null || oldStatus == undefined) {
        return [myObj];
      }
      if (oldStatus instanceof Array) {
        newObj = [...oldStatus, myObj];
      } else {
        if (oldStatus != undefined || oldStatus != null) {
          newObj = [oldStatus, myObj];
        } else {
          newObj = [myObj];
        }
      }
      return newObj;
    };

    const initStatusRealm = async () => {
      const oldStatus = await Database.get("PIMediaStatus");
      const myObj = {
        status: "uploading", // uploading, uploaded, failed
        uri: uri,
        imageName: DocumentImageName,
        activityId: activityId,
        quoteNumber: quoteNumber,
        regNumber: regNumber,
      };
      const newObj = addMediaStatusObj(oldStatus, myObj);
      await Database.set("PIMediaStatus", newObj);
      console.log(
        "*** UploadFile initStatusRealm after set newObj: " +
          JSON.stringify(newObj)
      );
    };

    await initStatusRealm();

    const handleProgress = async (event) => {
      // Start to track api call
      // UEStartTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
      if (DocumentImageName && DocumentImageName.includes("VDO")) {
        await Database.update("PIVideoCompleteStatus", {
          completePercentage: Math.round(event.loaded * 100) / event.total,
        });
      }
      // UELogEvent("handleProgress started", {
      //   "File Uploaded": JSON.stringify(
      //     Math.round(event.loaded * 100) / event.total
      //   ),
      //   "URL": JSON.stringify(SELFSURVEYSERVICE_DOCUMENT_URL)
      // });
      console.log(
        "File Uploaded => ",
        Math.round(event.loaded * 100) / event.total
      );
    };
    const documentUploadData = {
      activityId: activityId,
      data: null,
      dataUploadStatus: 0,
      fullName: activityId + "_" + DocumentImageName,
      geoLocation: {
        isBlocked: "",
        deviceName: deviceName,
        latitude: currentLatitude,
        longitude: currentLongitude,
        operatingSystem: DeviceInfo.getSystemVersion(),
        timezone: "Asia/Kolkata",
        deviceTime: null,
        ipAddress: IP,
        deviceIMEI: IMEI,
        macAddress: MAC,
        documentSource: "DigitEdge",
      },
      isLast: "false",
      isLastData: "false",
      isLastDocument: "false",
      isSurveyor: "false",
      manualOdometerReading:
        DocumentImageName == "ODO" ? PIOdometerData?.readings : "",
      source: "DIGITEDGE",
    };

    formData.append("file", {
      uri: uri,
      type: "image/jpeg",
      fileName: activityId + "_" + DocumentImageName,
      name: activityId + "_" + DocumentImageName + ext,
    });
    formData.append("documentData", JSON.stringify(documentUploadData));

    UELogEvent("UploadFile, Documentdata", {
      documentData: JSON.stringify(documentUploadData),
    });

    UELogEvent("started xhr events in uploadImage", {
      formdata: JSON.stringify(formData),
    });

    xhr.upload.addEventListener("progress", handleProgress);

    xhr.addEventListener("load", (load) => {
      UEEndTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
      UELogEvent("** UploadFile xhr load", {
        status: JSON.stringify(xhr.status),
        response: JSON.stringify(xhr.response),
      });

      /*
       * /document service is returning status 500
       * once the upload is done
       * if status is 200 video file uploads successfully
       * if status is 500, upload failed.
       */

      if (xhr.status === 200) {
        uploadSuccess();
        updateStatusRealm(activityId, DocumentImageName, "uploaded");
        console.log("*** UploadFile, Video upload success.");
        UELogEvent("** UploadFile xhr load, if xhr.status 200", {
          status: JSON.stringify(xhr.status),
          response: JSON.stringify(xhr.response),
        });
      } else {
        uploadFailure();
        updateStatusRealm(activityId, DocumentImageName, "failed");
        console.log(`*** UploadFile Video upload Failed, status ${xhr.status}`);
        UELogEvent("** UploadFile xhr load if xhr.status 500", {
          status: JSON.stringify(xhr.status),
          response: JSON.stringify(xhr.response),
        });
      }

      // uploadSuccess();

      // updateStatusRealm(realm, activityId, DocumentImageName, "uploaded");
    });

    xhr.addEventListener("abort", () => {
      UEEndTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
      UELogEvent("UploadFile xhr abort", {
        status: JSON.stringify(xhr.status),
      });
      uploadFailure();
      updateStatusRealm(activityId, DocumentImageName, "failed");
    });

    xhr.addEventListener("error", (error) => {
      UEEndTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
      uploadFailure();
      UELogEvent("UploadFile xhr error", {
        status: JSON.stringify(xhr.status),
        error: JSON.stringify(error),
      });
      updateStatusRealm(activityId, DocumentImageName, "failed");
      console.log("*** startUpolading error: " + JSON.stringify(error));
    });

    xhr.addEventListener("timeout", () => {
      UEEndTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
      UELogEvent("UploadFile xhr timeout", {
        status: JSON.stringify(xhr.status),
      });
      uploadFailure();
      updateStatusRealm(activityId, DocumentImageName, "failed");
    });

    xhr.open("POST", SELFSURVEYSERVICE_DOCUMENT_URL);
    xhr.setRequestHeader(
      "Accept",
      "*/*",
      "Content-Type",
      "multipart/form-data"
    );
    xhr.send(formData);
    UEStartTimer(SELFSURVEYSERVICE_DOCUMENT_URL);
  } catch (error) {
    console.log("*** UploadFile catch: " + error);
    await updateStatusRealm(activityId, DocumentImageName, "failed");
  }

  const updateStatusRealm = async (
    activityId,
    DocumentImageName,
    newStatus
  ) => {
    const uploadObj = await Database.get("PIMediaStatus");
    console.log(
      "*** UploadFile updateStatusRealm uploadObj: " + JSON.stringify(uploadObj)
    );
    if (uploadObj != null) {
      var newObj;
      if (uploadObj instanceof Array) {
        newObj = uploadObj.map((obj) =>
          obj.activityId === activityId &&
          obj.imageName === DocumentImageName &&
          obj.status !== newStatus
            ? { ...obj, imageName: DocumentImageName, status: newStatus }
            : obj
        );
      } else {
        newObj = [
          {
            ...uploadObj,
            activityId,
            imageName: DocumentImageName,
            status: newStatus,
          },
        ];
      }
      console.log(
        "*** UploadFile updateStatusRealm newObj: " + JSON.stringify(newObj)
      );
      await Database.set("PIMediaStatus", newObj);
    }
  };
}

export default UploadFile;
