<template>
  <div v-loading="loading" class="enhanced-upload">
    <div class="import-content">
      <div>
        <div class="upload-area" @click="triggerFileInput">
          <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
          <div class="el-upload__text">
            <span style="color: #409eff">点击上传</span>
          </div>
        </div>
        <input
          ref="fileInputRef"
          type="file"
          accept=".xls,.xlsx"
          style="display: none"
          @change="onFileChange"
        />
        <div class="custom-tip">
          <span>请上传Excel文件（.xls 或 .xlsx）</span>
        </div>
      </div>
      <div v-if="fileList.length > 0">
        <div
          v-for="(item, idx) in fileList"
          :key="idx"
          class="custom-file-item"
        >
          <el-icon class="file-icon"><Document /></el-icon>
          <div class="file-info">
            <div
              class="file-name"
              :title="`点击下载 ${item.path} 文件`"
              @click="downloadFile(item.path)"
            >
              {{ item?.filename || SetFileName(item.path) }}
            </div>
          </div>
          <el-icon class="delete-icon" @click="removeFile(idx)"
            ><Close
          /></el-icon>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import * as XLSX from 'xlsx'
import {
  ref,
  watch,
  defineProps,
  defineEmits,
  computed,
  defineExpose,
} from 'vue'
import { UploadFilled, Document, Close } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { uploadFileApi } from '@/api/common'
interface FileItem {
  path: string
  filename?: string
}
const props = defineProps<{
  modelValue: string
  importType: string
}>()
const emit = defineEmits(['update:modelValue', 'imported'])

const fileList = ref<FileItem[]>([])
const fileInputRef = ref<HTMLInputElement | null>(null)
const loading = ref(false)
const value = computed({
  get() {
    return props.modelValue
  },
  set(val: string) {
    emit('update:modelValue', val)
  },
})
watch(
  value,
  () => {
    let file: FileItem[] = []
    if (!Array.isArray(value)) {
      if (value.value) {
        file.push({ path: value.value })
      } else {
        file = []
      }
    }
    fileList.value = file
  },
  { immediate: true },
)

const triggerFileInput = () => {
  if (loading.value) return
  if (fileInputRef.value) fileInputRef.value?.click()
}
const downloadFile = (path: string) => {
  window.open(path)
}
const SetFileName = (path: string) => {
  if (!path) return ''
  const i = path.lastIndexOf('/')
  if (i === -1) return path
  return path.substring(i + 1)
}

const onFileChange = async (e: Event) => {
  const files = (e.target as HTMLInputElement).files
  if (!files) return
  const file = files[0]
  // 校验类型
  const isValidType = [
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  ].includes(file.type)
  if (!isValidType) {
    ElMessage.error('文件类型错误，请上传Excel文件')
    return
  }
  // 校验大小
  const isSizeValid = file.size / 1024 / 1024 < 50
  if (!isSizeValid) {
    ElMessage.error('文件大小不能超过50MB')
    return
  }
  if (props.importType === 'localAndUpload') {
    // 本地直接获取上传内容
    emit('imported', { path: file.name, data: file })
    if (fileInputRef.value) {
      fileInputRef.value.value = ''
    }
    loading.value = false
    return
  }
  if (props.importType === 'localAndXlsx') {
    // 本地解析,并自行处理xlsx数据
    const reader = new FileReader()
    reader.onload = (evt) => {
      const data = evt.target?.result
      const workbook = XLSX.read(data, { type: 'binary' })
      const firstSheetName = workbook.SheetNames[0]
      const worksheet = workbook.Sheets[firstSheetName]
      const jsonData = XLSX.utils.sheet_to_json(worksheet)
      //emit 路径和数据
      emit('imported', { path: file.name, data: jsonData })
      fileList.value = [{ path: file.name, filename: file.name }]
      value.value = file.name || ''
      ElMessage.success('导入成功')
      loading.value = false
    }
    reader.readAsBinaryString(file)
    if (fileInputRef.value) fileInputRef.value.value = ''
    return
  }
  // 走原有上传逻辑
  await fileUpload(file)
  if (fileInputRef.value) fileInputRef.value.value = ''
}
const resetUpload = () => {
  fileList.value = []
  value.value = ''
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

// 暴露重置方法给父组件
defineExpose({
  resetUpload,
})
const fileUpload = async (file: File) => {
  const formData = new FormData()
  const filename = file.name
  formData.append('file', file)
  formData.append('businessType', 'product')
  loading.value = true
  try {
    const res = await uploadFileApi(formData)
    fileList.value = [{ path: res.message ?? '', filename }]
    value.value = res.message ?? ''
    ElMessage.success('导入成功')
  } catch (e) {
    ElMessage.error('上传失败')
  } finally {
    loading.value = false
  }
}

const removeFile = (idx: number) => {
  fileList.value.splice(idx, 1)
  value.value = ''
}
</script>

<style scoped lang="scss">
.enhanced-upload {
  .import-content {
    padding: 20px 0;
  }
  .custom-file-item {
    display: flex;
    align-items: center;
    padding: 12px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    margin-top: 8px;
    background: #fff;
    .file-icon {
      font-size: 24px;
      color: #52c41a;
      margin-right: 12px;
    }
    .file-info {
      flex-grow: 1;
      .file-name {
        color: #333;
        margin-bottom: 4px;
      }
      .file-name:hover {
        text-decoration: underline;
        color: blue;
      }
    }
    .delete-icon {
      color: #f56c6c;
      font-size: 20px;
      cursor: pointer;
      margin-left: 10px;
      &:hover {
        color: #ff0000;
      }
    }
  }
  .upload-area {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    padding: 40px 20px;
    // background: #fafafa;
    background: var(--el-fill-color-blank);
    cursor: pointer;
    &:hover {
      border-color: var(--el-color-primary);
    }
    .el-icon--upload {
      font-size: 70px;
      color: #a8abb2;
      margin-bottom: 12px;
    }
    .el-upload__text {
      color: #666;
    }
  }
  .custom-tip {
    display: flex;
    align-items: center;
    color: #666;
    margin-top: 12px;
    i {
      margin-right: 6px;
    }
  }
}
</style>
