import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _regeneratorRuntime from "@babel/runtime/regenerator";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
import FileReaderInput from "react-file-reader-input";
import Cropper from "react-cropper";
import ceil from "lodash-es/ceil";
import ReactCSSTransitionGroup from "react-addons-css-transition-group";
import classnames from "classnames";
import "cropperjs/dist/cropper.css";
import Card from "../Card";
import Dialog from "../Dialog";
import TextField from "../TextField";
import Typography from "../Typography";
import IconButton from "../IconButton";
import Upload from "../Icon/Upload";
import ImageIcon from "../Icon/Image";
import Link from "../Icon/Link";
import Enter from "../Icon/Enter";
import Loader from "../Loading";
import getClasses from "./styles";
import { resizeBase64ForMaxWidth, resizeBase64ForMaxHeight } from "./resizer";
import { isValidUrl, getImageDimensions } from "./image";
var availableMimetypes = ["image/jpg", "image/png", "image/jpeg"];

var ImageUpload = function ImageUpload(props) {
  var classes = getClasses();
  var minHeight = props.minHeight,
      minWidth = props.minWidth,
      aspect = props.aspect,
      getBase64FromUrlApi = props.getBase64FromUrlApi,
      className = props.className;
  var image = props.image,
      logo = props.logo,
      mobile = props.mobile,
      onSubmit = props.onSubmit,
      copies = props.copies,
      mbLimit = props.mbLimit,
      images = props.images;

  var _useState = useState({
    logoUrl: ""
  }),
      _useState2 = _slicedToArray(_useState, 2),
      uploadDialog = _useState2[0],
      setUploadDialog = _useState2[1];

  var _useState3 = useState(""),
      _useState4 = _slicedToArray(_useState3, 2),
      croppedImage = _useState4[0],
      setCroppedImage = _useState4[1];

  var _useState5 = useState(false),
      _useState6 = _slicedToArray(_useState5, 2),
      isLoading = _useState6[0],
      setIsLoading = _useState6[1];

  var _useState7 = useState(false),
      _useState8 = _slicedToArray(_useState7, 2),
      openUrl = _useState8[0],
      setOpenUrl = _useState8[1];

  var _useState9 = useState(false),
      _useState10 = _slicedToArray(_useState9, 2),
      openFile = _useState10[0],
      setOpenFile = _useState10[1];

  var _useState11 = useState(false),
      _useState12 = _slicedToArray(_useState11, 2),
      openInvalidUrl = _useState12[0],
      setOpenInvalidUrl = _useState12[1];

  var _useState13 = useState(false),
      _useState14 = _slicedToArray(_useState13, 2),
      openUploadError = _useState14[0],
      setOpenUploadError = _useState14[1];

  var _useState15 = useState(false),
      _useState16 = _slicedToArray(_useState15, 2),
      openInvalidFileFormat = _useState16[0],
      setOpenInvalidFileFormat = _useState16[1];

  var _useState17 = useState(false),
      _useState18 = _slicedToArray(_useState17, 2),
      showUrl = _useState18[0],
      setShowUrl = _useState18[1];

  var _useState19 = useState(undefined),
      _useState20 = _slicedToArray(_useState19, 2),
      base64Img = _useState20[0],
      setBase64Img = _useState20[1];

  var refLink = useRef(null);
  var refFile = useRef(null);
  useEffect(function () {
    if (image) {
      setUploadDialog({
        logoUrl: "",
        hasError: false
      });
      setBase64Img(image);
    }
  }, []);

  var hideErrorInUpdateDialog = function hideErrorInUpdateDialog() {
    setOpenInvalidFileFormat(false);
    setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
      hasError: false
    }));
  };

  var updateLogo = /*#__PURE__*/function () {
    var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
      var finalImage, dimensions, successCallback, errorCallback, res;
      return _regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              finalImage = "";
              setOpenFile(false);
              setOpenUrl(false);
              setIsLoading(true);
              hideErrorInUpdateDialog();
              _context.next = 7;
              return getImageDimensions(croppedImage.toDataURL());

            case 7:
              dimensions = _context.sent;

              if (!(dimensions.height > 300 || dimensions.width > 300)) {
                _context.next = 20;
                break;
              }

              successCallback = function successCallback(resizedImage) {
                finalImage = resizedImage;
              };

              errorCallback = function errorCallback() {
                setOpenUploadError(true);
              };

              if (!(dimensions.height > dimensions.width)) {
                _context.next = 16;
                break;
              }

              _context.next = 14;
              return resizeBase64ForMaxHeight(croppedImage.toDataURL(), 300, 300, successCallback, errorCallback);

            case 14:
              _context.next = 18;
              break;

            case 16:
              _context.next = 18;
              return resizeBase64ForMaxWidth(croppedImage.toDataURL(), 300, 300, successCallback, errorCallback);

            case 18:
              _context.next = 21;
              break;

            case 20:
              finalImage = croppedImage.toDataURL();

            case 21:
              _context.next = 23;
              return onSubmit(finalImage);

            case 23:
              res = _context.sent;
              setOpenFile(false);
              setOpenUrl(false);
              setIsLoading(false);

              if (res !== null && res !== void 0 && res.error) {
                // error during upload
                setOpenUploadError(true);
              } else {
                // successful upload
                setOpenUploadError(false);
              }

            case 28:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));

    return function updateLogo() {
      return _ref.apply(this, arguments);
    };
  }();

  var handleChangeFile = function handleChangeFile(event, results) {
    var _results$ = _slicedToArray(results[0], 2),
        e = _results$[0],
        file = _results$[1];

    var base64 = e.target.result;
    var fileSize = 4 * ceil(base64.length / 3);

    if (!!file && !!file.type) {
      if (availableMimetypes.indexOf(file.type) !== -1 && fileSize < mbLimit * 1000000) {
        setUploadDialog({
          logoUrl: ""
        });
        setShowUrl(false);
        setBase64Img(base64);
        setOpenFile(true);
      } else {
        setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
          logoUrl: "",
          hasError: true
        }));
        setOpenInvalidFileFormat(true);
      }
    }

    return false;
  };

  var handleShowURL = function handleShowURL() {
    setShowUrl(!showUrl);
  };

  var handleUrlChange = function handleUrlChange(evt) {
    var logoUrl = evt.target.value;
    setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
      logoUrl: logoUrl,
      hasError: false
    }));
  };

  var updateLogoUrlValue = /*#__PURE__*/function () {
    var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
      var logoUrl, _yield$getBase64FromU, base64;

      return _regeneratorRuntime.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              logoUrl = uploadDialog.logoUrl;

              if (!isValidUrl(logoUrl)) {
                _context2.next = 10;
                break;
              }

              setIsLoading(true);
              _context2.next = 5;
              return getBase64FromUrlApi(logoUrl);

            case 5:
              _yield$getBase64FromU = _context2.sent;
              base64 = _yield$getBase64FromU.base64;

              if (!base64) {
                setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
                  logoUrl: logoUrl,
                  hasError: true
                }));
                setOpenInvalidUrl(true);
              } else {
                setIsLoading(false);
                setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
                  logoUrl: logoUrl,
                  hasError: false
                }));
                setBase64Img(base64);
                setOpenUrl(true);
              }

              _context2.next = 12;
              break;

            case 10:
              setUploadDialog(_objectSpread(_objectSpread({}, uploadDialog), {}, {
                logoUrl: logoUrl,
                hasError: true
              }));
              setOpenInvalidUrl(true);

            case 12:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    }));

    return function updateLogoUrlValue() {
      return _ref2.apply(this, arguments);
    };
  }();

  var updateLogoUrlValueEnter = function updateLogoUrlValueEnter(event) {
    if (event.key === "Enter") {
      updateLogoUrlValue();
    }
  };

  var crop = function crop() {
    // image in dataUrl
    if (openFile) {
      setCroppedImage(refFile.current.cropper.getCroppedCanvas());
    } else if (openUrl) {
      setCroppedImage(refLink.current.cropper.getCroppedCanvas());
    }
  };

  return /*#__PURE__*/React.createElement("div", {
    className: classnames(classes.root, className)
  }, !!logo && /*#__PURE__*/React.createElement("div", {
    className: classes.newLogo
  }, !isLoading && /*#__PURE__*/React.createElement("img", {
    src: logo,
    className: classes.imagePreview,
    alt: "logo"
  }), isLoading && /*#__PURE__*/React.createElement(Loader, {
    size: 60,
    center: true,
    className: classes.loader
  })), !logo && /*#__PURE__*/React.createElement(Card, {
    variant: "striped",
    className: classes.logoPlaceholder
  }, !isLoading && /*#__PURE__*/React.createElement(ImageIcon, {
    size: 32
  }), isLoading && /*#__PURE__*/React.createElement(Loader, {
    size: 60,
    center: true,
    className: classes.loader
  })), /*#__PURE__*/React.createElement("div", {
    className: mobile ? classnames(classes.actions, classes.actionsMobile) : classes.actions
  }, /*#__PURE__*/React.createElement(FileReaderInput, {
    id: "my-file-input",
    onChange: handleChangeFile,
    className: classes.hiddeInput
  }, /*#__PURE__*/React.createElement(IconButton, {
    outlined: false,
    color: "primary",
    className: classes.uploadLogoBtn,
    icon: /*#__PURE__*/React.createElement(Upload, null)
  })), /*#__PURE__*/React.createElement(IconButton, {
    outlined: false,
    onClick: function onClick() {
      return handleShowURL(showUrl);
    },
    color: "primary",
    active: showUrl,
    icon: /*#__PURE__*/React.createElement(Link, null),
    className: classes.iconButton
  }), /*#__PURE__*/React.createElement(ReactCSSTransitionGroup, {
    transitionName: {
      enter: classes.inputEnter,
      enterActive: classes.inputEnterActive,
      leave: classes.inputLeave,
      leaveActive: classes.inputLeaveActive
    },
    className: classes.inputTransition,
    transitionEnterTimeout: 500,
    transitionLeaveTimeout: 300
  }, showUrl ? /*#__PURE__*/React.createElement("div", {
    className: classes.urlInputContainer
  }, /*#__PURE__*/React.createElement(TextField, {
    variant: "standard",
    className: classes.input,
    value: uploadDialog.logoUrl,
    onChange: function onChange(evt) {
      return handleUrlChange(evt);
    },
    onKeyPress: updateLogoUrlValueEnter,
    size: "small"
  })) : null), /*#__PURE__*/React.createElement(ReactCSSTransitionGroup, {
    transitionName: {
      enter: classes.buttonEnter,
      enterActive: classes.buttonEnterActive,
      leave: classes.buttonLeave,
      leaveActive: classes.buttonLeaveActive
    },
    transitionEnterTimeout: 500,
    transitionLeaveTimeout: 300
  }, showUrl ? /*#__PURE__*/React.createElement(IconButton, {
    outlined: false,
    color: "primary",
    onClick: updateLogoUrlValue,
    icon: /*#__PURE__*/React.createElement(Enter, null),
    className: classes.iconButton
  }) : null)), /*#__PURE__*/React.createElement(Dialog, {
    open: openUrl,
    onClose: function onClose() {
      return setOpenUrl(false);
    },
    title: copies.cropper.title,
    buttonPrimary: {
      label: copies.cropper.chooseImageButton,
      onClick: updateLogo,
      isLoading: isLoading
    }
  }, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
    variant: "body1",
    align: "center",
    className: classes.panel
  }, copies.cropper.howTo), /*#__PURE__*/React.createElement(Cropper, {
    ref: refLink,
    src: base64Img,
    className: classes.cropper,
    aspectRatio: aspect,
    ready: crop,
    cropend: crop,
    zoom: crop,
    minCropBoxWidth: minWidth,
    minCropBoxHeight: minHeight
  }))), /*#__PURE__*/React.createElement(Dialog, {
    open: openInvalidUrl,
    onClose: function onClose() {
      return setOpenInvalidUrl(false);
    },
    title: copies.errors.invalidUrl,
    image: images.warning,
    buttonPrimary: {
      label: copies.closeButton,
      onClick: function onClick() {
        return setOpenInvalidUrl(false);
      }
    }
  }), /*#__PURE__*/React.createElement(Dialog, {
    open: openFile,
    onClose: function onClose() {
      return setOpenFile(false);
    },
    title: copies.cropper.title,
    buttonPrimary: {
      label: copies.cropper.chooseImageButton,
      onClick: updateLogo,
      isLoading: isLoading
    }
  }, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
    variant: "body1",
    align: "center",
    className: classes.panel
  }, copies.cropper.howTo), /*#__PURE__*/React.createElement(Cropper, {
    ref: refFile,
    src: base64Img,
    className: classes.cropper,
    aspectRatio: aspect,
    ready: crop,
    cropend: crop,
    minCropBoxWidth: minWidth,
    minCropBoxHeight: minHeight
  }))), /*#__PURE__*/React.createElement(Dialog, {
    open: openInvalidFileFormat,
    onClose: function onClose() {
      return setOpenInvalidFileFormat(false);
    },
    title: copies.errors.invalidFileFormat,
    image: images.warning,
    buttonPrimary: {
      label: copies.closeButton,
      onClick: function onClick() {
        return setOpenInvalidFileFormat(false);
      }
    }
  }), /*#__PURE__*/React.createElement(Dialog, {
    open: openUploadError,
    onClose: function onClose() {
      return setOpenUploadError(false);
    },
    title: copies.errors.errorUploadingImage,
    image: images.warning,
    buttonPrimary: {
      label: copies.closeButton,
      onClick: function onClick() {
        return setOpenUploadError(false);
      }
    }
  }));
};

ImageUpload.propTypes = {
  onSubmit: PropTypes.func,
  minWidth: PropTypes.number,
  minHeight: PropTypes.number,
  aspect: PropTypes.number,
  mbLimit: PropTypes.number,
  image: PropTypes.string,
  images: PropTypes.instanceOf(Object),
  getBase64FromUrlApi: PropTypes.func.isRequired
};
ImageUpload.defaultProps = {
  onSubmit: function onSubmit() {},
  minHeight: 144,
  minWidth: 144,
  aspect: null,
  image: "",
  mbLimit: 10,
  images: {}
};
export default ImageUpload;