import * as MediaLibrary from "expo-media-library";
import React, { useEffect, useState } from "react";

import {
  ActivityIndicator,
  Alert,
  Modal,
  StyleSheet,
  Text,
  View,
} from "react-native";
import { ProgressBar } from "react-native-paper";
import Toast from "react-native-toast-message";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { logImEXEvent } from "../../firebase/firebase.analytics";
import {
  selectCurrentCameraJobId,
  selectDeleteAfterUpload,
} from "../../redux/app/app.selectors";
import * as Sentry from "@sentry/react-native";

import { formatBytes } from "../../util/document-upload.utility";
import { handleLocalUpload } from "../../util/local-document-upload.utility";

const mapStateToProps = createStructuredSelector({
  selectedCameraJobId: selectCurrentCameraJobId,
  deleteAfterUpload: selectDeleteAfterUpload,
});

export default connect(mapStateToProps, null)(UploadProgress);

export function UploadProgress({
  selectedCameraJobId,
  deleteAfterUpload,
  uploads,
  setUploads,
  forceRerender,
}) {
  const [progress, setProgress] = useState({
    loading: false,
    uploadInProgress: false,
    speed: 0,
  });

  useEffect(() => {
    //Set the state of uploads to do.
    if (uploads) {
      beginUploads(uploads);
      setUploads(null);
    }
  }, [uploads]);

  async function handleOnSuccess({ duration, data }) {
    //If it's not in production, show a toast with the time.
    Toast.show({
      type: "success",
      text1: ` Upload completed in ${duration}.`,
      //
      //   text2: duration,
    });
    if (deleteAfterUpload) {
      try {
        await MediaLibrary.deleteAssetsAsync(data);

        const album = await MediaLibrary.createAlbumAsync(
          "ImEX Mobile Deleted",
          data.pop(),
          false
        );
        //Move the rest.
        if (data.length > 0) {
          const moveResult = await MediaLibrary.addAssetsToAlbumAsync(
            data,
            album,
            false
          );
        }
        const deleteResult = await MediaLibrary.deleteAlbumsAsync(album);
      } catch (error) {
        console.log("Unable to delete picture.", error);
        Sentry.Native.captureException(error);
      }
    }

    logImEXEvent("imexmobile_successful_upload");
    forceRerender();
    setProgress({ ...progress, speed: 0, percent: 1, uploadInProgress: false });
  }

  function handleOnProgress({ percent, loaded }) {
    setProgress((progress) => ({
      ...progress,
      speed: loaded - progress.loaded,
      loaded: loaded,
      percent,
    }));
  }

  function handleOnError({ assetid, error }) {
    logImEXEvent("imexmobile_upload_documents_error");
    Toast.show({
      type: "error",
      text1: "Unable to upload documents.",
      text2: error,
      autoHide: false,
    });
    setProgress({
      speed: 0,
      percent: 1,
      uploadInProgress: false,
    });
  }

  const beginUploads = async (data) => {
    //Validate to make sure the totals for the file sizes do not exceed the total on the job.
    setProgress({
      percent: 0,
      loaded: 0,
      uploadInProgress: true,
      start: new Date(),
      average: 0,
    });

    await handleLocalUpload({
      files: data,
      onError: ({ assetid, error }) => handleOnError({ assetid, error }),
      onProgress: ({ percent, loaded }) =>
        handleOnProgress({ percent, loaded }),
      onSuccess: ({ duration }) => handleOnSuccess({ duration, data }),
      context: {
        jobid:
          selectedCameraJobId !== "temp" ? selectedCameraJobId : "temporary",
      },
    });
  };

  return (
    <Modal
      visible={progress.uploadInProgress}
      animationType="slide"
      transparent={true}
      onRequestClose={() => {
        Alert.alert("Cancel?", "Do you want to abort the upload?", [
          {
            text: "Yes",
            onPress: () => {
              setUploads(null);
              setProgress(null);
            },
          },
          { text: "No" },
        ]);
      }}
    >
      <View style={styles.modalContainer}>
        <View style={styles.modal}>
          <ActivityIndicator style={{ alignSelf: "center", marginTop: 16 }} />
          <ProgressBar
            progress={progress.percent}
            style={{ alignSelf: "center", marginTop: 16 }}
            color={progress.percent === 1 ? "green" : "blue"}
          />
          <Text style={{ alignSelf: "center", marginTop: 16 }}>{`${formatBytes(
            progress.speed
          )}/sec`}</Text>
          <Text
            style={{ alignSelf: "center", marginTop: 16 }}
          >{`Avg. ${formatBytes(
            progress.loaded / ((new Date() - progress.start) / 1000)
          )}/sec`}</Text>
          <Text
            style={{ alignSelf: "center", marginTop: 16 }}
          >{`Total Uploaded ${formatBytes(progress.loaded)}`}</Text>
          <Text style={{ alignSelf: "center", marginTop: 16 }}>{`Duration ${(
            (new Date() - progress.start) /
            1000
          ).toFixed(1)} sec`}</Text>
        </View>
      </View>
    </Modal>
  );
}
const styles = StyleSheet.create({
  modalContainer: {
    display: "flex",
    flex: 1,
    justifyContent: "center",
  },
  modal: {
    // flex: 1,
    display: "flex",
    marginLeft: 20,
    marginRight: 20,
    backgroundColor: "white",
    borderRadius: 20,
    padding: 18,
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 4,
    elevation: 5,
  },
});
