<template>
  <uploader
    v-model="files"
    class="wl-uploader"
    data-weiling-mobile-ui-wl-uploader
    :after-read="afterRead"
    :before-read="beforeRead"
    :max-size="maxSize"
    @oversize="onOversize"
    :accept="accept"
    v-bind="$attrs"
    @delete="onDelete"
  >
    <template
      v-if="slot.default"
      #default
    >
      <slot name="default" />
    </template>
    <template #preview-delete>
      <img
        class="uploader_close"
        :src="CloseSpIcon"
        alt=""
      />
    </template>
    <template
      v-if="slot['preview-cover']"
      #preview-cover="file"
    >
      <!-- <img class="uploader_mask_close" @click.stop="delImg(file)" :src="CloseSpIcon" alt="" /> -->
      <slot
        name="preview-cover"
        :file="file"
      />
    </template>
  </uploader>
  <Teleport :to="teleport">
    <ImgCropper
      v-model:value="currentFile"
      :file="currentFile"
      :cropperOption="cropperOption"
      @onCroppered="onCroppered"
    />
  </Teleport>
</template>

<script lang="ts">
/*
 * @Author:XINKAI
 * @Last Modified by: Liao.xiuli
 * @Last Modified time: 2023-10-25 15:37:32
 */
export default {
  name: "WlUploader",
};
</script>

<script setup lang="ts">
import { Uploader } from "vant";
import ImgCropper from "./component/ImgCropper.vue";
import Store from "@mobileUI/store";
import { sizeTostr } from "@mobileUI/utils";
import { ref, useSlots, watch } from "vue";
import useUpload from "@mobileUI/hooks/useUpload";
import useMessage from "@mobileUI/hooks/useMessage";
import CloseSpIcon from "@mobileUI/assets/images/close-sp.png";
import { TUploaderFileList } from "../type";

const { onError } = useMessage();
const { onFileAfterRead, onFileBeforeRead } = useUpload();

type Props = {
  fileList?: TUploaderFileList[];
  env_data: TEnv.TEnvData;
  maxSize?: string | number; // 文件大小限制，单位为 byte
  accept?: string;
  cropper?: boolean; // 是否需要裁剪
  cropperOption?: any; // 裁剪组件的配置
  teleport?: string;
};
const props = withDefaults(defineProps<Props>(), {
  env_data: () => {
    return {
      sid: "",
      domain: "",
      corp_id: "",
      node_env: "dev",
      app_id: "",
      token: "",
      card_resource: "",
    };
  },
  maxSize: 20 * 1024 * 1024,
  fileList: () => [],
  accept: "",
  cropper: false,
  cropperOption: () => { },
  teleport: "body"
});
Store.corp_id = props.env_data.corp_id;
Store.sid = props.env_data.sid;
Store.node_env = props.env_data.node_env;
Store.token = props.env_data.token;
Store.card_resource = props.env_data.card_resource;
const slot = ref(useSlots());
const files = ref<TUploaderFileList[]>([]);
const currentFile = ref<TUploaderFileList>(null);
const emit = defineEmits<{
  (e: "onGetUploadImagesUrl", val: TUploaderFileList[]);
}>();

const emitFileList = () => {
  const list = files.value?.filter((res) => res.url);
  emit("onGetUploadImagesUrl", list);
};
const delImg = (data) => {
  files.value.splice(data.index, 1);
  emitFileList();
};
const afterRead = (data) => {
  if (props.cropper) {
    currentFile.value = data;
    return;
  }
  data.status = "uploading";
  data.message = "上传中...";
  data.deletable = true;
  onFileAfterRead({
    file: data.file,
  })
    .then((res: any) => {
      data.status = "done";
      data.url = res.cos_url;
      emitFileList();
    })
    .catch(() => {
      data.message = "上传失败";
      data.status = "failed";
    });
};

const onDelete = () => {
  emitFileList();
};

// 格式/大小 校验
const onOversize = () => {
  if (props.maxSize) onError(`文件大小不能超过 ${sizeTostr(props.maxSize)}`);
};
const beforeRead = (file) => {
  return onFileBeforeRead(file, props.accept);
};

// 截取之后上传
const onCroppered = ({ file, content }) => {
  const i = files.value.findIndex((res) => res == currentFile.value) || 0;
  if (!content) {
    files.value?.splice(i, 1);
    return;
  }
  files.value[i].status = "uploading";
  files.value[i].message = "上传中...";
  files.value[i].deletable = true;
  currentFile.value = null;
  onFileAfterRead({
    file,
  })
    .then((res: any) => {
      files.value[i].status = "done";
      files.value[i].url = res.cos_url;
      files.value[i].content = content;
      emitFileList();
    })
    .catch(() => {
      files.value[i].message = "上传失败";
      files.value[i].status = "failed";
    });
};
watch(
  () => props.fileList,
  (res) => files.value = res,
  { immediate: true }
);
</script>

<style lang="scss">
.wl-uploader[data-weiling-mobile-ui-wl-uploader] {
  border-radius: 8px;

  .van-uploader__preview,
  .van-uploader__upload {
    border-radius: 6px;
    overflow: hidden;
  }

  .uploader_mask_close {
    width: 14px;
    height: 14px;
    position: absolute;
    z-index: 1;
    right: 0;
    top: 0;
  }

  .uploader_close {
    width: 14px;
    height: 14px;
  }

  .uploader_close {
    width: 14px;
    height: 14px;
  }
}
</style>
