import { Modal, notification, Upload } from "antd";
import { InboxOutlined } from "@ant-design/icons";
import axios from "axios";
import React, { useState } from "react";
import { useMutation } from "react-apollo";
import { useTranslation } from "react-i18next";
import Resizer from "react-image-file-resizer";
import {
  INSERT_NEW_DOCUMENT,
  DELETE_DOCUMENT
} from "../../graphql/documents.queries";
import "./jobs-documents.styles.scss";
import { generateCdnThumb } from "../../utils/DocHelpers";

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

function JobsDocumentsComponent({ shopId, jobId, loading, data, currentUser }) {
  const { t } = useTranslation();
  const [insertNewDocument] = useMutation(INSERT_NEW_DOCUMENT);
  const [deleteDocument] = useMutation(DELETE_DOCUMENT);

  const [state, setState] = useState({
    previewVisible: false,
    previewImage: ""
  });

  const [fileList, setFileList] = useState(
    data.reduce((acc, value) => {
      acc.push({
        uid: value.id,
        url: value.thumb_url,
        name: value.name,
        status: "done",
        full_url: value.url,
        key: value.key
      });
      return acc;
    }, [])
  );

  const uploadToS3 = (
    fileName,
    fileType,
    file,
    onError,
    onSuccess,
    onProgress
  ) => {
    axios
      .post("/sign_s3", {
        fileName,
        fileType
      })
      .then(response => {
        var returnData = response.data.data.returnData;
        var signedRequest = returnData.signedRequest;
        var url = returnData.url;
        setState({ ...state, url: url });
        // Put the fileType in the headers for the upload
        var options = {
          headers: {
            "Content-Type": fileType
          },
          onUploadProgress: e => {
            onProgress({ percent: (e.loaded / e.total) * 100 });
          }
        };

        axios
          .put(signedRequest, file, options)
          .then(response => {
            console.log("response from axios", response);
            insertNewDocument({
              variables: {
                docInput: [
                  {
                    jobid: jobId,
                    uploaded_by: currentUser.email,
                    url,
                    thumb_url: generateCdnThumb(fileName),
                    key: fileName
                  }
                ]
              }
            }).then(r => {
              onSuccess({
                uid: r.data.insert_documents.returning[0].id,
                url: r.data.insert_documents.returning[0].thumb_url,
                name: r.data.insert_documents.returning[0].name,
                status: "done",
                full_url: r.data.insert_documents.returning[0].url,
                key: r.data.insert_documents.returning[0].key
              });
              notification["success"]({
                message: t("documents.successes.insert")
              });
            });

            setState({ ...state, success: true });
          })
          .catch(error => {
            console.log("Error uploading to S3", error);
            onError(error);
            notification["error"]({
              message: t("documents.errors.insert") + JSON.stringify(error)
            });
          });
      })
      .catch(error => {
        console.log("Outside Error here.", error);
        notification["error"]({
          message: t("documents.errors.getpresignurl") + JSON.stringify(error)
        });
      });
  };

  const handleUpload = ev => {
    const { onError, onSuccess, onProgress } = ev;
    //If PDF, upload directly.
    //If JPEG, resize and upload.
    let key = `${shopId}/${jobId}/${ev.file.name}`;
    if (ev.file.type === "application/pdf") {
      console.log("It's a PDF.");
      uploadToS3(key, ev.file.type, ev.file, onError, onSuccess, onProgress);
    } else {
      Resizer.imageFileResizer(
        ev.file,
        3000,
        3000,
        "JPEG",
        75,
        0,
        uri => {
          let file = new File([uri], ev.file.name, {});
          file.uid = ev.file.uid;
          uploadToS3(key, file.type, file, onError, onSuccess, onProgress);
        },
        "blob"
      );
    }
  };
  const handleCancel = () => setState({ ...state, previewVisible: false });

  const handlePreview = async file => {
    if (!file.full_url && !file.url) {
      file.preview = await getBase64(file.originFileObj);
    }

    setState({
      ...state,
      previewImage: file.full_url || file.url,
      previewVisible: true
    });
  };
  const handleChange = props => {
    const { event, fileList, file } = props;
    //Required to ensure that the state accurately reflects new data and that images can be deleted in feeded.
    if (!event) {
      //SPread the new file in where the old one was.
      const newFileList = fileList.map(i =>
        i.uid === file.uid ? Object.assign({}, i, file.response) : i
      );
      setFileList(newFileList);
    } else {
      setFileList(fileList);
    }
  };

  const { previewVisible, previewImage } = state;

  const handleRemove = file => {
    console.log("file", file);

    //Remove the file on S3
    axios
      .post("/delete_s3", { fileName: file.key })
      .then(response => {
        //Delete the record in our database.
        if (response.status === 200) {
          deleteDocument({ variables: { id: file.uid } }).then(r => {
            notification["success"]({
              message: t("documents.successes.delete")
            });
          });
        } else {
          notification["error"]({
            message:
              1 +
              t("documents.errors.deletes3") +
              JSON.stringify(response.message)
          });
        }
      })
      .catch(error => {
        notification["error"]({
          message: "2" + t("documents.errors.deletes3") + JSON.stringify(error)
        });
      });
  };

  return (
    <div className="clearfix">
      <button
        onClick={() => {
          const imageRequest = JSON.stringify({
            bucket: process.env.REACT_APP_S3_BUCKET,
            key:
              "52b7357c-0edd-4c95-85c3-dfdbcdfad9ac/c8ca5761-681a-4bb3-ab76-34c447357be3/Invoice_353284489.pdf",
            edits: { format: "jpeg" }
          });
          const CloudFrontUrl = "https://d18fc493a0fm4o.cloudfront.net";
          const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;
          console.log("url", url);
        }}
      >
        Test PDF
      </button>
      <Upload.Dragger
        customRequest={handleUpload}
        accept=".pdf,.jpg,.jpeg"
        listType="picture-card"
        fileList={fileList}
        multiple={true}
        onPreview={handlePreview}
        onRemove={handleRemove}
        onChange={handleChange}
      >
        <p className="ant-upload-drag-icon">
          <InboxOutlined />
        </p>
        <p className="ant-upload-text">
          Click or drag file to this area to upload
        </p>
        <p className="ant-upload-hint">
          Support for a single or bulk upload. Strictly prohibit from uploading
          company data or other band files
        </p>
      </Upload.Dragger>
      <Modal visible={previewVisible} footer={null} onCancel={handleCancel}>
        <img alt="example" style={{ width: "100%" }} src={previewImage} />
      </Modal>
    </div>
  );
}
export default JobsDocumentsComponent;
