<script lang="ts">
export default {
  name: "c-upload",
};
</script>

<script lang="ts" setup>
import { PlusOutlined, InboxOutlined } from "@ant-design/icons-vue";
import { Modal } from "ant-design-vue";
import { ref, computed, useSlots } from "vue";

defineProps({
  type: {
    type: String,
    default: "normal",
  },
  showSlot: {
    type: Boolean,
    default: true,
  },
});

const previewVisible = ref(false);

const previewImage = ref("");

const $slots = useSlots();

const showCustomItem = computed(() =>
  Object.keys($slots).includes("itemRender")
);

const getBase64 = (file: File) => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
};

const handlePreview = async (file) => {
  if (!file.url && !file.preview) {
    file.preview = (await getBase64(file.originFileObj)) as string;
  }
  previewImage.value = file.url || file.preview;
  previewVisible.value = true;
};

const handleCancel = () => {
  previewVisible.value = false;
};

defineExpose({
  getBase64,
});
</script>

<template>
  <a-upload v-bind="$attrs" v-if="type === 'normal'" @preview="handlePreview">
    <slot v-if="showSlot">
      <div class="upload-text">
        <plus-outlined />
        <div style="margin-top: 8px">上传</div>
      </div>
    </slot>
    <template #itemRender="data" v-if="showCustomItem">
      <slot name="itemRender" v-bind="data"></slot>
    </template>
  </a-upload>
  <a-upload-dragger v-bind="$attrs" v-if="type === 'drag'">
    <slot v-if="showSlot">
      <p class="ant-upload-drag-icon">
        <inbox-outlined />
      </p>
      <p class="ant-upload-text">点击或拖入文件以上传</p>
      <p class="ant-upload-hint">支持单个或多个文件上传</p>
    </slot>
  </a-upload-dragger>
  <modal
    :visible="previewVisible"
    title="预览"
    :footer="null"
    @cancel="handleCancel"
  >
    <img style="width: 100%" :src="previewImage" />
  </modal>
</template>

<style lang="less" scoped>
.upload-text {
  text-align: center;
}
</style>
