import React, { useContext, useState } from "react";
import { uploadFile, getCancelToken } from "../../services/uploadFile";

const FileUploadContext = React.createContext();

export const FileUploadProvider = ({ children }) => {
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);
  const [status, setStatus] = useState(null);
  const [cancelUpload, setCancelUpload] = useState(null);
  const [linkURL, setLinkURL] = useState(null);
  const [files, setFiles] = useState(null);

  const done = () => {
    setCancelUpload(null);
    setUploading(false);
    setProgress(0);
  };

  const cancel = async () => {
    if (cancelUpload && progress < 100) {
      cancelUpload.cancel();
      setStatus("Upload cancelled");
    }
    done();
  };

  const validateUpload = (formData, accessToken, uploadFiles) => {
    if (!formData) {
      throw new Error("Missing package update data");
    }

    if (!formData.packagename || formData.packagename.length === 0) {
      throw new Error("Package name required");
    }

    if (!formData.version || formData.version.length === 0) {
      throw new Error("Package update version required");
    }

    if (!formData.vehicles || formData.vehicles.length === 0) {
      throw new Error("Vehicles required");
    }

    if (!uploadFiles || uploadFiles.length === 0) {
      throw new Error("File required");
    }

    if (!accessToken || accessToken.length === 0) {
      throw new Error("Access token required");
    }
  };

  const upload = async (formData, accessToken, uploadFiles) => {
    validateUpload(formData, accessToken, uploadFiles);

    try {
      const file = uploadFiles[0];
      const filename = file.name;

      setUploading(true);
      setLinkURL(null);
      setProgress(0);
      setStatus(`Uploading ${filename}`);
      setCancelUpload(getCancelToken());

      const { data } = await uploadFile(
        file,
        formData,
        accessToken,
        setProgress,
        cancelUpload
      );
      if (data.message) {
        throw new Error(`${data.error}. ${data.message}`);
      }
      const url = data && data.link ? data.link : "No URL available";
      setLinkURL(url);
      setStatus(`Uploaded ${filename}`);
      setCancelUpload(null);
      setProgress(100);
    } catch (e) {
      setUploading(true);
      setStatus(`Error occured: ${e.message}`);
      setProgress(-1);
    }
  };

  return (
    <FileUploadContext.Provider
      value={{
        uploading,
        progress,
        status,
        linkURL,
        files,
        upload,
        cancel,
        setFiles,
      }}
    >
      {children}
    </FileUploadContext.Provider>
  );
};

export const useFileUploadContext = () => useContext(FileUploadContext);
