import { defineComponent, computed, toRef, ref, onMounted, createVNode } from 'vue';
import '../../../utils/index.mjs';
import '../../../locale/index.mjs';
import '../../../hooks/index.mjs';
import '../../../vue-components/index.mjs';
import '../../locale-provider/index.mjs';
import useConfigInject from '../../config-provider/src/hooks/useConfigInject.mjs';
import '../../config-provider/index.mjs';
import '../../form/index.mjs';
import useStyle from '../style/index.mjs';
import UploadList from './UploadList/index.mjs';
import { uploadProps } from './interface.mjs';
import { file2Obj, updateFileList, getFileItem, removeFileItem } from './utils.mjs';
import { initDefaultProps } from '../../../utils/vue/initDefaultProps.mjs';
import { useInjectFormItemContext } from '../../form/src/FormItemContext.mjs';
import { useInjectDisabled } from '../../config-provider/src/context/disabledContext.mjs';
import { useMergedState } from '../../../hooks/use-merged-state/index.mjs';
import { devWarning } from '../../../utils/log.mjs';
import { useLocaleReceiver } from '../../locale-provider/src/useLocaleReceiver.mjs';
import localeValues from '../../../locale/lang/en_US.mjs';
import { classNames } from '../../../utils/dom/class.mjs';
import VcUpload from '../../../vue-components/vc-upload/src/Upload.mjs';
import { flattenChildren } from '../../../utils/vue/props.mjs';

const LIST_IGNORE = `__LIST_IGNORE_${Date.now()}__`;
var AUpload = /* @__PURE__ */ defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "AUpload",
  inheritAttrs: false,
  props: initDefaultProps(uploadProps(), {
    type: "select",
    multiple: false,
    action: "",
    data: {},
    accept: "",
    showUploadList: true,
    listType: "text",
    // or picture
    supportServerRender: true
  }),
  setup(props, {
    slots,
    attrs,
    expose
  }) {
    const formItemContext = useInjectFormItemContext();
    const {
      prefixCls,
      direction,
      disabled
    } = useConfigInject("upload", props);
    const [wrapSSR, hashId] = useStyle(prefixCls);
    const disabledContext = useInjectDisabled();
    const mergedDisabled = computed(() => {
      var _a;
      return (_a = disabled.value) != null ? _a : disabledContext.value;
    });
    const [mergedFileList, setMergedFileList] = useMergedState(props.defaultFileList || [], {
      value: toRef(props, "fileList"),
      postState: (list) => {
        const timestamp = Date.now();
        return (list != null ? list : []).map((file, index) => {
          if (!file.uid && !Object.isFrozen(file))
            file.uid = `__AUTO__${timestamp}_${index}__`;
          return file;
        });
      }
    });
    const dragState = ref("drop");
    const upload = ref(null);
    onMounted(() => {
      devWarning(props.fileList !== void 0 || attrs.value === void 0, "Upload", "`value` is not a valid prop, do you mean `fileList`?");
      devWarning(props.transformFile === void 0, "Upload", "`transformFile` is deprecated. Please use `beforeUpload` directly.");
      devWarning(props.remove === void 0, "Upload", "`remove` props is deprecated. Please use `remove` event.");
    });
    const onInternalChange = (file, changedFileList, event) => {
      var _a, _b;
      let cloneList = [...changedFileList];
      if (props.maxCount === 1)
        cloneList = cloneList.slice(-1);
      else if (props.maxCount)
        cloneList = cloneList.slice(0, props.maxCount);
      setMergedFileList(cloneList);
      const changeInfo = {
        file,
        fileList: cloneList
      };
      if (event)
        changeInfo.event = event;
      (_a = props["onUpdate:fileList"]) == null ? void 0 : _a.call(props, changeInfo.fileList);
      (_b = props.onChange) == null ? void 0 : _b.call(props, changeInfo);
      formItemContext.onFieldChange();
    };
    const mergedBeforeUpload = async (file, fileListArgs) => {
      const {
        beforeUpload,
        transformFile
      } = props;
      let parsedFile = file;
      if (beforeUpload) {
        const result = await beforeUpload(file, fileListArgs);
        if (result === false)
          return false;
        delete file[LIST_IGNORE];
        if (result === LIST_IGNORE) {
          Object.defineProperty(file, LIST_IGNORE, {
            value: true,
            configurable: true
          });
          return false;
        }
        if (typeof result === "object" && result)
          parsedFile = result;
      }
      if (transformFile)
        parsedFile = await transformFile(parsedFile);
      return parsedFile;
    };
    const onBatchStart = (batchFileInfoList) => {
      const filteredFileInfoList = batchFileInfoList.filter((info) => !info.file[LIST_IGNORE]);
      if (!filteredFileInfoList.length)
        return;
      const objectFileList = filteredFileInfoList.map((info) => file2Obj(info.file));
      let newFileList = [...mergedFileList.value];
      objectFileList.forEach((fileObj) => {
        newFileList = updateFileList(fileObj, newFileList);
      });
      objectFileList.forEach((fileObj, index) => {
        let triggerFileObj = fileObj;
        if (!filteredFileInfoList[index].parsedFile) {
          const {
            originFileObj
          } = fileObj;
          let clone;
          try {
            clone = new File([originFileObj], originFileObj.name, {
              type: originFileObj.type
            });
          } catch (e) {
            clone = new Blob([originFileObj], {
              type: originFileObj.type
            });
            clone.name = originFileObj.name;
            clone.lastModifiedDate = /* @__PURE__ */ new Date();
            clone.lastModified = (/* @__PURE__ */ new Date()).getTime();
          }
          clone.uid = fileObj.uid;
          triggerFileObj = clone;
        } else {
          fileObj.status = "uploading";
        }
        onInternalChange(triggerFileObj, newFileList);
      });
    };
    const onSuccess = (response, file, xhr) => {
      try {
        if (typeof response === "string")
          response = JSON.parse(response);
      } catch (e) {
      }
      if (!getFileItem(file, mergedFileList.value))
        return;
      const targetItem = file2Obj(file);
      targetItem.status = "done";
      targetItem.percent = 100;
      targetItem.response = response;
      targetItem.xhr = xhr;
      const nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList);
    };
    const onProgress = (e, file) => {
      if (!getFileItem(file, mergedFileList.value))
        return;
      const targetItem = file2Obj(file);
      targetItem.status = "uploading";
      targetItem.percent = e.percent;
      const nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList, e);
    };
    const onError = (error, response, file) => {
      if (!getFileItem(file, mergedFileList.value))
        return;
      const targetItem = file2Obj(file);
      targetItem.error = error;
      targetItem.response = response;
      targetItem.status = "error";
      const nextFileList = updateFileList(targetItem, mergedFileList.value);
      onInternalChange(targetItem, nextFileList);
    };
    const handleRemove = (file) => {
      let currentFile;
      const mergedRemove = props.onRemove || props.remove;
      Promise.resolve(typeof mergedRemove === "function" ? mergedRemove(file) : mergedRemove).then((ret) => {
        var _a, _b;
        if (ret === false)
          return;
        const removedFileList = removeFileItem(file, mergedFileList.value);
        if (removedFileList) {
          currentFile = {
            ...file,
            status: "removed"
          };
          (_a = mergedFileList.value) == null ? void 0 : _a.forEach((item) => {
            const matchKey = currentFile.uid !== void 0 ? "uid" : "name";
            if (item[matchKey] === currentFile[matchKey] && !Object.isFrozen(item))
              item.status = "removed";
          });
          (_b = upload.value) == null ? void 0 : _b.abort(currentFile);
          onInternalChange(currentFile, removedFileList);
        }
      });
    };
    const onFileDrop = (e) => {
      var _a;
      dragState.value = e.type;
      if (e.type === "drop")
        (_a = props.onDrop) == null ? void 0 : _a.call(props, e);
    };
    expose({
      onBatchStart,
      onSuccess,
      onProgress,
      onError,
      fileList: mergedFileList,
      upload
    });
    const [locale] = useLocaleReceiver("Upload", localeValues.Upload, computed(() => props.locale));
    const renderUploadList = (button, buttonVisible) => {
      const {
        removeIcon,
        previewIcon,
        downloadIcon,
        previewFile,
        onPreview,
        onDownload,
        isImageUrl,
        progress,
        itemRender,
        iconRender,
        showUploadList
      } = props;
      const {
        showDownloadIcon,
        showPreviewIcon,
        showRemoveIcon
      } = typeof showUploadList === "boolean" ? {} : showUploadList;
      return showUploadList ? createVNode(UploadList, {
        "prefixCls": prefixCls.value,
        "listType": props.listType,
        "items": mergedFileList.value,
        "previewFile": previewFile,
        "onPreview": onPreview,
        "onDownload": onDownload,
        "onRemove": handleRemove,
        "showRemoveIcon": !mergedDisabled.value && showRemoveIcon,
        "showPreviewIcon": showPreviewIcon,
        "showDownloadIcon": showDownloadIcon,
        "removeIcon": removeIcon,
        "previewIcon": previewIcon,
        "downloadIcon": downloadIcon,
        "iconRender": iconRender,
        "locale": locale.value,
        "isImageUrl": isImageUrl,
        "progress": progress,
        "itemRender": itemRender,
        "appendActionVisible": buttonVisible,
        "appendAction": button
      }, {
        ...slots
      }) : button == null ? void 0 : button();
    };
    return () => {
      var _a, _b;
      const {
        listType,
        type
      } = props;
      const {
        class: className,
        style: styleName,
        ...transAttrs
      } = attrs;
      const rcUploadProps = {
        onBatchStart,
        onError,
        onProgress,
        onSuccess,
        ...transAttrs,
        ...props,
        id: (_a = props.id) != null ? _a : formItemContext.id.value,
        prefixCls: prefixCls.value,
        beforeUpload: mergedBeforeUpload,
        onChange: void 0,
        disabled: mergedDisabled.value
      };
      delete rcUploadProps.remove;
      if (!slots.default || mergedDisabled.value)
        delete rcUploadProps.id;
      const rtlCls = {
        [`${prefixCls.value}-rtl`]: direction.value === "rtl"
      };
      if (type === "drag") {
        const dragCls = classNames(prefixCls.value, {
          [`${prefixCls.value}-drag`]: true,
          [`${prefixCls.value}-drag-uploading`]: mergedFileList.value.some((file) => file.status === "uploading"),
          [`${prefixCls.value}-drag-hover`]: dragState.value === "dragover",
          [`${prefixCls.value}-disabled`]: mergedDisabled.value,
          [`${prefixCls.value}-rtl`]: direction.value === "rtl"
        }, attrs.class, hashId.value);
        return wrapSSR(createVNode("span", {
          ...attrs,
          "class": classNames(`${prefixCls.value}-wrapper`, rtlCls, className, hashId.value)
        }, [createVNode("div", {
          "class": dragCls,
          "onDrop": onFileDrop,
          "onDragover": onFileDrop,
          "onDragleave": onFileDrop,
          "style": attrs.style
        }, [createVNode(VcUpload, {
          ...rcUploadProps,
          "ref": upload,
          "class": `${prefixCls.value}-btn`
        }, {
          default: () => {
            var _a2;
            return [createVNode("div", {
              "class": `${prefixCls.value}-drag-container`
            }, [(_a2 = slots.default) == null ? void 0 : _a2.call(slots)])];
          },
          ...slots
        })]), renderUploadList()]));
      }
      const uploadButtonCls = classNames(prefixCls.value, {
        [`${prefixCls.value}-select`]: true,
        [`${prefixCls.value}-select-${listType}`]: true,
        [`${prefixCls.value}-disabled`]: mergedDisabled.value,
        [`${prefixCls.value}-rtl`]: direction.value === "rtl"
      });
      const children = flattenChildren((_b = slots.default) == null ? void 0 : _b.call(slots));
      const renderUploadButton = (uploadButtonStyle) => createVNode("div", {
        "class": uploadButtonCls,
        "style": uploadButtonStyle
      }, [createVNode(VcUpload, {
        ...rcUploadProps,
        "ref": upload
      }, slots)]);
      if (listType === "picture-card") {
        return wrapSSR(createVNode("span", {
          ...attrs,
          "class": classNames(`${prefixCls.value}-wrapper`, `${prefixCls.value}-picture-card-wrapper`, rtlCls, attrs.class, hashId.value)
        }, [renderUploadList(renderUploadButton, !!(children && children.length))]));
      }
      return wrapSSR(createVNode("span", {
        ...attrs,
        "class": classNames(`${prefixCls.value}-wrapper`, rtlCls, attrs.class, hashId.value)
      }, [renderUploadButton(children && children.length ? void 0 : {
        display: "none"
      }), renderUploadList()]));
    };
  }
});

export { LIST_IGNORE, AUpload as default };
//# sourceMappingURL=Upload.mjs.map
