"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.ImageUploader = void 0;
var _tslib = require("tslib");
var _ahooks = require("ahooks");
var _antdMobileIcons = require("antd-mobile-icons");
var _react = _interopRequireWildcard(require("react"));
var _measureCssLength = require("../../utils/measure-css-length");
var _nativeProps = require("../../utils/native-props");
var _usePropsValue = require("../../utils/use-props-value");
var _withDefaultProps = require("../../utils/with-default-props");
var _configProvider = require("../config-provider");
var _grid = _interopRequireDefault(require("../grid"));
var _imageViewer = _interopRequireDefault(require("../image-viewer"));
var _space = _interopRequireDefault(require("../space"));
var _previewItem = _interopRequireDefault(require("./preview-item"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const classPrefix = `adm-image-uploader`;
const defaultProps = {
  disableUpload: false,
  deletable: true,
  deleteIcon: _react.default.createElement(_antdMobileIcons.CloseOutline, {
    className: `${classPrefix}-cell-delete-icon`
  }),
  showUpload: true,
  multiple: false,
  maxCount: 0,
  defaultValue: [],
  accept: 'image/*',
  preview: true,
  showFailed: true,
  imageFit: 'cover'
};
const ImageUploader = exports.ImageUploader = (0, _react.forwardRef)((p, ref) => {
  const {
    locale
  } = (0, _configProvider.useConfig)();
  const props = (0, _withDefaultProps.mergeProps)(defaultProps, p);
  const {
    columns
  } = props;
  const [value, setValue] = (0, _usePropsValue.usePropsValue)(props);
  const [tasks, setTasks] = (0, _react.useState)([]);
  const containerRef = (0, _react.useRef)(null);
  const containerSize = (0, _ahooks.useSize)(containerRef);
  const gapMeasureRef = (0, _react.useRef)(null);
  const [cellSize, setCellSize] = (0, _react.useState)(80);
  const inputRef = (0, _react.useRef)(null);
  (0, _ahooks.useIsomorphicLayoutEffect)(() => {
    const gapMeasure = gapMeasureRef.current;
    if (columns && containerSize && gapMeasure) {
      const width = containerSize.width;
      const gap = (0, _measureCssLength.measureCSSLength)(window.getComputedStyle(gapMeasure).getPropertyValue('height'));
      setCellSize((width - gap * (columns - 1)) / columns);
    }
  }, [containerSize === null || containerSize === void 0 ? void 0 : containerSize.width]);
  const style = {
    '--cell-size': cellSize + 'px'
  };
  (0, _ahooks.useIsomorphicLayoutEffect)(() => {
    setTasks(prev => prev.filter(task => {
      if (task.url === undefined) return true;
      return !value.some(fileItem => fileItem.url === task.url);
    }));
  }, [value]);
  (0, _ahooks.useIsomorphicLayoutEffect)(() => {
    var _a;
    (_a = props.onUploadQueueChange) === null || _a === void 0 ? void 0 : _a.call(props, tasks.map(item => ({
      id: item.id,
      status: item.status
    })));
  }, [tasks]);
  const idCountRef = (0, _react.useRef)(0);
  const {
    maxCount,
    onPreview,
    renderItem
  } = props;
  function processFile(file, fileList) {
    return (0, _tslib.__awaiter)(this, void 0, void 0, function* () {
      const {
        beforeUpload
      } = props;
      let transformedFile = file;
      transformedFile = yield beforeUpload === null || beforeUpload === void 0 ? void 0 : beforeUpload(file, fileList);
      return transformedFile;
    });
  }
  function getFinalTasks(tasks) {
    return props.showFailed ? tasks : tasks.filter(task => task.status !== 'fail');
  }
  const finalTasks = getFinalTasks(tasks);
  function onChange(e) {
    return (0, _tslib.__awaiter)(this, void 0, void 0, function* () {
      var _a;
      e.persist();
      const {
        files: rawFiles
      } = e.target;
      if (!rawFiles) return;
      let files = [].slice.call(rawFiles);
      e.target.value = ''; // HACK: fix the same file doesn't trigger onChange
      if (props.beforeUpload) {
        const postFiles = files.map(file => processFile(file, files));
        yield Promise.all(postFiles).then(filesList => {
          files = filesList.filter(Boolean);
        });
      }
      if (files.length === 0) {
        return;
      }
      if (maxCount > 0) {
        const exceed = value.length + files.length + finalTasks.length - maxCount;
        if (exceed > 0) {
          files = files.slice(0, files.length - exceed);
          (_a = props.onCountExceed) === null || _a === void 0 ? void 0 : _a.call(props, exceed);
        }
      }
      const newTasks = files.map(file => ({
        id: idCountRef.current++,
        status: 'pending',
        file
      }));
      setTasks(prev => [...getFinalTasks(prev), ...newTasks]);
      const newVal = [];
      yield Promise.all(newTasks.map((currentTask, index) => (0, _tslib.__awaiter)(this, void 0, void 0, function* () {
        try {
          const result = yield props.upload(currentTask.file);
          newVal[index] = result;
          setTasks(prev => {
            return prev.map(task => {
              if (task.id === currentTask.id) {
                return Object.assign(Object.assign({}, task), {
                  status: 'success',
                  url: result.url
                });
              }
              return task;
            });
          });
        } catch (e) {
          setTasks(prev => {
            return prev.map(task => {
              if (task.id === currentTask.id) {
                return Object.assign(Object.assign({}, task), {
                  status: 'fail'
                });
              }
              return task;
            });
          });
          console.error(e);
        }
      })));
      setValue(prev => prev.concat(newVal).filter(Boolean));
    });
  }
  const imageViewerHandlerRef = (0, _react.useRef)(null);
  function previewImage(index) {
    imageViewerHandlerRef.current = _imageViewer.default.Multi.show({
      images: value.map(fileItem => fileItem.url),
      defaultIndex: index,
      onClose: () => {
        imageViewerHandlerRef.current = null;
      }
    });
  }
  (0, _ahooks.useUnmount)(() => {
    var _a;
    (_a = imageViewerHandlerRef.current) === null || _a === void 0 ? void 0 : _a.close();
  });
  const showUpload = props.showUpload && (maxCount === 0 || value.length + finalTasks.length < maxCount);
  const renderImages = () => {
    return value.map((fileItem, index) => {
      var _a, _b;
      const originNode = _react.default.createElement(_previewItem.default, {
        key: (_a = fileItem.key) !== null && _a !== void 0 ? _a : index,
        url: (_b = fileItem.thumbnailUrl) !== null && _b !== void 0 ? _b : fileItem.url,
        deletable: props.deletable,
        deleteIcon: props.deleteIcon,
        imageFit: props.imageFit,
        onClick: () => {
          if (props.preview) {
            previewImage(index);
          }
          onPreview && onPreview(index, fileItem);
        },
        onDelete: () => (0, _tslib.__awaiter)(void 0, void 0, void 0, function* () {
          var _c;
          const canDelete = yield (_c = props.onDelete) === null || _c === void 0 ? void 0 : _c.call(props, fileItem);
          if (canDelete === false) return;
          setValue(value.filter((x, i) => i !== index));
        })
      });
      return renderItem ? renderItem(originNode, fileItem, value) : originNode;
    });
  };
  const contentNode = _react.default.createElement(_react.default.Fragment, null, renderImages(), tasks.map(task => {
    if (!props.showFailed && task.status === 'fail') {
      return null;
    }
    return _react.default.createElement(_previewItem.default, {
      key: task.id,
      file: task.file,
      deletable: task.status !== 'pending',
      deleteIcon: props.deleteIcon,
      status: task.status,
      imageFit: props.imageFit,
      onDelete: () => {
        setTasks(tasks.filter(x => x.id !== task.id));
      }
    });
  }), _react.default.createElement("div", {
    className: `${classPrefix}-upload-button-wrap`,
    style: showUpload ? undefined : {
      display: 'none'
    }
  }, props.children || _react.default.createElement("span", {
    className: `${classPrefix}-cell ${classPrefix}-upload-button`,
    role: 'button',
    "aria-label": locale.ImageUploader.upload
  }, _react.default.createElement("span", {
    className: `${classPrefix}-upload-button-icon`
  }, _react.default.createElement(_antdMobileIcons.AddOutline, null))), !props.disableUpload && _react.default.createElement("input", {
    "aria-label": locale.ImageUploader.upload,
    ref: inputRef,
    capture: props.capture,
    accept: props.accept,
    multiple: props.multiple,
    type: 'file',
    className: `${classPrefix}-input`,
    onChange: onChange
  })));
  (0, _react.useImperativeHandle)(ref, () => ({
    get nativeElement() {
      return inputRef.current;
    }
  }));
  return (0, _nativeProps.withNativeProps)(props, _react.default.createElement("div", {
    className: classPrefix,
    ref: containerRef
  }, columns ? _react.default.createElement(_grid.default, {
    className: `${classPrefix}-grid`,
    columns: columns,
    style: style
  }, _react.default.createElement("div", {
    className: `${classPrefix}-gap-measure`,
    ref: gapMeasureRef
  }), contentNode.props.children) : _react.default.createElement(_space.default, {
    className: `${classPrefix}-space`,
    wrap: true,
    block: true
  }, contentNode.props.children)));
});