<template>
  <div
    :style="{ width: width + 'px', height: height + 'px' }"
    class="border-dashed border rounded overflow-hidden border-[#ccc] relative"
  >
    <!-- 显示图片/视频 -->
    <div v-if="!fileSource" class="absolute w-full h-full flex justify-center items-center">
      <div class="flex flex-col items-center cursor-pointer" @click="getFile">
        <el-icon size="30" color="#ccc"><Plus /></el-icon>
        上传文件
      </div>
    </div>
    <!-- 有资源 -->
    <div v-else class="absolute w-full h-full group">
      <div v-if="percent === 100">
        <img
          v-if="fileSource && fileType === 'img'"
          :src="fileSource"
          alt=""
          class="absolute w-full h-full object-fill"
        />
        <video
          v-if="fileSource && fileType === 'video'"
          :src="fileSource"
          alt=""
          controls
          class="absolute w-full h-full object-fill"
        />
        <div class="absolute w-full h-full opacity-30 bg-black hidden group-hover:block"></div>
        <div class="absolute w-full h-full justify-center items-center hidden group-hover:flex">
          <el-icon size="20" color="#fff" class="cursor-pointer" @click="preview"
            ><ZoomIn
          /></el-icon>
          <el-icon size="20" color="#fff" class="cursor-pointer ml-3" @click="deleteFile"
            ><Delete
          /></el-icon>
        </div>
      </div>
      <div v-else class="w-full h-full flex justify-center items-center">
        <el-progress type="circle" :percentage="percent" />
      </div>
    </div>
    <input type="file" ref="fileRef" class="hidden" :accept="fileAccept" @change="fileChange" />
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { Plus, ZoomIn, Delete } from '@element-plus/icons-vue'
import { uploadRequest } from '@/api/upload'
import { ElMessage } from 'element-plus'
const props = withDefaults(
  defineProps<{
    fileSize?: number
    fileAccept?: string
    uploadType?: 'img' | 'video'
    width: number
    height: number
    modelValue?: number | string
  }>(),
  {
    fileSize: 2,
    fileAccept: '.png,.jpg,.jpeg',
    uploadType: 'img'
  }
)
const emit = defineEmits<{
  (event: 'update:modelValue', id: number | string): void
}>()
const fileSource = ref<string>('')
const fileRef = ref<HTMLInputElement>()
const percent = ref(0)
const fileType = ref<'img' | 'video'>(props.uploadType)
watch(
  () => {
    return props.modelValue
  },
  (value) => {
    if (!value) {
      fileSource.value = ''
      percent.value = 100
    }
  },
  {
    immediate: true
  }
)
const getFile = () => {
  fileRef.value?.click()
}
const fileChange = async (e: Event) => {
  const file = (e.target as HTMLInputElement).files!
  const fileAccept = props.fileAccept.split(',')
  if (!file[0]) return
  const type = file[0].type
  //验证文件格式是否正确
  if (!fileAccept.includes(`.${type.split('/')[1]}`)) {
    ElMessage({
      type: 'error',
      message: '格式不正确'
    })
    return
  }
  //验证文件大小是否正确
  if (file[0].size > props.fileSize * 1024 * 1024) {
    ElMessage({
      type: 'error',
      message: `大小不能超过${props.fileSize}M`
    })
    return
  }
  //判定文件类型
  if (type.indexOf('image') !== -1) {
    fileType.value = 'img'
  } else {
    fileType.value = 'video'
  }
  //开始上传
  fileSource.value = window.URL.createObjectURL(file[0])
  const res = await uploadRequest(file[0], (e) => {
    const progress = e.progress?.toFixed(2)
    const total = (progress as unknown as number) * 100
    percent.value = total
  })
  emit('update:modelValue', res.data!)
  ElMessage({
    type: 'success',
    message: '上传成功'
  })
}
const deleteFile = () => {
  fileSource.value = ''
  percent.value = 0
  fileRef.value!.value = ''
  emit('update:modelValue', '')
}
// todo
const preview = () => {
  console.log('preview')
}
</script>

<style scoped></style>
