<script setup lang="ts">
import { StrAnyObj } from '@/typings'
import { getToken, removeToken } from '@/utils'
import { ElMessage } from 'element-plus'
import router from '@/router'

const LOGIN_URL = import.meta.env.VITE_LOGIN_URL

const props = withDefaults(
  defineProps<{
    modelValue: string | undefined
    tip?: string
    limit?: number
    disabled?: boolean
    width?: string
  }>(),
  {
    disabled: false,
    width: '350px'
  }
)

const fileList = ref([])

const emits = defineEmits(['update:modelValue'])

const computedModelValue = computed({
  get() {
    return props.modelValue ? JSON.parse(props.modelValue) : []
  },
  set(newValue) {
    const result = newValue.map((item) => {
      return { name: item.name, url: item.url }
    })
    emits('update:modelValue', JSON.stringify(result))
  }
})

watch(
  computedModelValue,
  (data) => {
    fileList.value = data
  },
  {
    immediate: true
  }
)

const headers = ref({})
const action = import.meta.env.VITE_APP_BASE_API + '/file/upload'

const beforeUpload = () => {
  headers.value = { Authorization: getToken() }
}

const onSuccess = (resp: StrAnyObj) => {
  // 登录失效
  if (resp.code == 401) {
    removeToken()
    ElMessage.error(resp.message)
    router.replace(LOGIN_URL).then()
    return Promise.reject(resp)
  } else if (resp.code != 200) {
    ElMessage.error(resp.message)
    return Promise.reject(resp)
  }
  computedModelValue.value = [...computedModelValue.value, resp.data]
  ElMessage.success('上传成功')
}

const onRemove = (data) => {
  computedModelValue.value = computedModelValue.value.filter(
    (item) => item.url !== data?.response?.data?.url && item.url !== data.url
  )
}

const onPreview = (data) => {
  window.open(data.url, '_blank')
}

const onError = (data) => {
  ElMessage.error(`文件上传失败：${data.message}`)
}

const onExceed = () => {
  ElMessage.error(`最多上传${props.limit}个文件`)
}
</script>

<template>
  <el-upload
    :file-list="fileList"
    :headers="headers"
    :action="action"
    :multiple="!limit || limit > 1"
    :before-upload="beforeUpload"
    :on-success="onSuccess"
    :on-remove="onRemove"
    :on-preview="onPreview"
    :on-error="onError"
    :on-exceed="onExceed"
    :limit="limit"
    :style="{ width }"
  >
    <el-button type="primary" :disabled="disabled">上传文件</el-button>
    <template v-if="tip && !disabled" #tip>
      <div class="el-upload__tip">
        {{ tip }}
      </div>
    </template>
  </el-upload>
</template>

<style scoped lang="scss"></style>
