<script setup lang="ts">
import { computed, ref, unref } from "vue";
import { useVModel } from "@vueuse/core";
import { ElMessage } from "element-plus";
import { httpImgUpload } from "/@/api/components/upload";
import { useResponseHandle } from "/@/hooks/useAsync";
import { getToken } from "/@/utils/auth";
import { loadEnv } from "@build/index";
import { Plus } from "@element-plus/icons-vue";
import { useRenderIcon } from "../../ReIcon/src/hooks";

const emit = defineEmits(["change", "update:urls"]);

const props = withDefaults(
  defineProps<{
    descs?: string[];
    types?: string[];
    size?: number;
    urls: string[];
    disabled?: boolean;
  }>(),
  {
    size: 1
  }
);
const { VITE_PROXY_DOMAIN_REAL } = loadEnv();
const baseUrl = `${VITE_PROXY_DOMAIN_REAL}storage/`;
const token = getToken();
const inputer = ref(null);
const loading = ref(false);
const imageTypes = computed(() => {
  const { types } = props;
  return types.map(type => "image/" + type);
});
const imageUrls = useVModel(props, "urls");
const responseHandle = useResponseHandle();

const onBeforeImageUpload = ({ type, size }) => {
  if (!imageTypes.value.includes(type)) {
    ElMessage.warning(`请上传${props.types.join(".")}类型的图片`);
    return false;
  }
  if (size / 1024 / 1024 > props.size) {
    ElMessage.warning("图片大小超过" + props.size + "M");
    return false;
  }
  return true;
};
function handleRemove(url: string) {
  const index = imageUrls.value.findIndex(u => u === url);
  if (index >= 0) {
    imageUrls.value.splice(index, 1);
  }
}

const handleChange = async () => {
  if (loading.value) return;
  const files = inputer.value.files;
  const length = files.length;
  if (length === 0) return;
  loading.value = true;
  for (let i = 0; i <= length; i++) {
    if (i === length) {
      loading.value = false;
      inputer.value = null;
    } else {
      const url = await httpupLoad(files, i);
      if (!(url === "break" || url === "error")) {
        imageUrls.value.push(url);
        emit("change", unref(imageUrls));
      }
    }
  }
};

const httpupLoad = (file, i): Promise<string> => {
  return new Promise(resolve => {
    if (!onBeforeImageUpload(file[i])) {
      resolve("break");
    }

    const _formData = new FormData();
    _formData.append("image", file[i]);
    _formData.append("token", token);

    httpImgUpload(_formData).then(res => {
      const { message, code, data } = res;
      responseHandle({
        message,
        code,
        handler: () => {
          const url = baseUrl + data[0].url;
          resolve(url);
        }
        // errorHandler: () => {
        //   resolve("break");
        // }
      });
    });
  });
};
</script>

<template>
  <ul class="image-upload-list">
    <li
      class="img-show relative"
      v-for="(item, index) in imageUrls"
      :key="index + item"
    >
      <img :src="item" alt="" />

      <div class="absolute top-[-3px] right-[5px]" v-show="!disabled">
        <ElButton
          link
          size="large"
          type="primary"
          :icon="useRenderIcon('close-bold')"
          @click="() => handleRemove(item)"
        />
      </div>
    </li>

    <li class="img-input" v-show="!disabled">
      <input
        ref="inputer"
        v-loading="loading"
        :accept="types.join('.')"
        :multiple="true"
        type="file"
        name="file"
        :disabled="disabled"
        @change="handleChange"
      />
      <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
    </li>
  </ul>
</template>

<style lang="scss" scoped>
.image-upload-list {
  --el-upload-list-picture-card-size: 65px;
  display: inline-flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
  position: relative;
  li {
    padding: 0;
    list-style: none;
    position: relative;
    &.img-show {
      overflow: hidden;
      background-color: var(--el-fill-color-blank);
      border: 1px solid var(--el-border-color);
      border-radius: 6px;
      box-sizing: border-box;
      width: var(--el-upload-list-picture-card-size);
      height: var(--el-upload-list-picture-card-size);
      margin: 0 8px 8px 0;
      padding: 0;
      display: inline-flex;
    }
    &.img-input {
      --el-upload-picture-card-size: 65px;
      background-color: var(--el-fill-color-lighter);
      border: 1px dashed var(--el-border-color-darker);
      border-radius: 6px;
      box-sizing: border-box;
      width: var(--el-upload-picture-card-size);
      height: var(--el-upload-picture-card-size);
      cursor: pointer;
      vertical-align: top;
      display: inline-flex;
      justify-content: center;
      align-items: center;
      input {
        opacity: 0;
        width: 100%;
        height: 100%;
        outline: none;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 2;
      }
      .el-icon.avatar-uploader-icon {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
        font-size: 28px;
        color: #8c939d;
        width: 100%;
        height: 100%;
        text-align: center;
      }
    }
  }
}
</style>
