<template>
  <div class="file-uploader-container" 
  :class="{'hide-upload-btn': !(!limit || fileList.length < limit), 'is-upload-avatar': isUploadAvatar}">
    <el-upload
      ref="uploadRef"
      :action="uploadUrl"
      :headers="headers"
      :method="method"
      :multiple="multiple"
      :data="uploadData"
      :name="fileFieldName"
      :with-credentials="withCredentials"
      :show-file-list="showFileList"
      :accept="accept"
      :limit="limit"
      :file-list="fileList"
      :auto-upload="autoUpload"
      :drag="drag"
      :list-type="listType"
      :before-upload="handleBeforeUpload"
      :before-remove="handleBeforeRemove"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :on-change="handleChange"
      :on-remove="handleRemove"
      :on-exceed="handleExceed"
      :on-preview="handlePreview"
      :on-download="handleDownload"
    >
      <template v-if="drag">
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          {{$t('common.dragUpload')}} <em>{{$t('common.clickUpload')}}</em>
        </div>
        <template v-if="tip" class="el-upload__tip">{{ tip }}</template>
      </template>

      <template v-else-if="listType === 'picture-card'">
        <!-- 只有当文件数量小于limit且limit大于0时才显示加号按钮 -->
        <!--  v-if="!limit || fileList.length < limit" -->
        <el-avatar :size="80" :src="fileList[0]?.url || appStore.avatarDefault" v-if="isUploadAvatar" />
        <el-icon v-else-if="!limit || fileList.length < limit" ><Plus /></el-icon>
      </template>
      <template v-else-if="listType === 'picture-user-card'">
        <!-- 只有当文件数量小于limit且limit大于0时才显示加号按钮 -->
        <!--  v-if="!limit || fileList.length < limit" -->
        <!-- <el-icon v-if="!limit || fileList.length < limit" ><Plus /></el-icon> -->
        
  
      </template>

      
      
      <template v-else>
        <slot name="trigger">
          <el-button type="primary" class="gradient" size="large">
            <el-icon><Plus /></el-icon>
            <span class="ml10">{{ buttonText }}</span>
          </el-button>
        </slot>
        <template v-if="tip" class="el-upload__tip">
          <span class="ml10 gray999">{{ tip }}</span>
        </template>
      </template>
      
      <template >
        <div v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item">
          <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
          <span class="el-upload-list__item-actions">
            <span
              class="el-upload-list__item-preview"
              @click="handlePreview(file,index)"
            >
              <el-icon><zoom-in /></el-icon>
            </span>
            <!-- <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleDownload(file)"
            >
              <el-icon><Download /></el-icon>
            </span> -->
            <span
              v-if="!disabled"
              class="el-upload-list__item-delete"
              @click="handleRemove(file,index)"
            >
              <el-icon><Delete /></el-icon>
            </span>
          </span>
        </div>
        <!-- <slot name="file-list" :file-list="fileList">
          <el-upload-list :file-list="fileList" @remove="handleRemove">
            <template #default="{ file }">
              <el-upload-list-item
                :file="file"
                :name="fileFieldName"
                @remove="handleRemove"
              >
                <template #actions>
                  <el-button
                    type="text"
                    size="small"
                    @click="handlePreview(file)"
                  >
                    <el-icon><zoom-in /></el-icon>
                    预览
                  </el-button>
                  <el-button
                    type="text"
                    size="small"
                    @click="handleDownload(file)"
                  >
                    <el-icon><download /></el-icon>
                    下载
                  </el-button>
                  <el-button
                    type="text"
                    size="small"
                    @click="handleRemove(file)"
                  >
                    <el-icon><delete /></el-icon>
                    删除
                  </el-button>
                </template>
              </el-upload-list-item>
            </template>
          </el-upload-list>
        </slot> -->
      </template>
      
      <!-- 上传进度条 -->
      <template v-if="showProgress" #progress="{ file }">
        <el-progress
          :percentage="file.percentage"
          :stroke-width="2"
          :show-text="false"
        />
      </template>
    </el-upload>
    
    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewVisible"
      :title="previewTitle"
      width="50%"
      destroy-on-close
    >
      <div class="preview-container">
        <template v-if="isImageFile(currentPreviewFile)">
          <img :src="currentPreviewFile.url" alt="预览" class="preview-image" />
        </template>
        
        <template v-else-if="isTextFile(currentPreviewFile)">
          <pre class="preview-text">{{ currentPreviewContent }}</pre>
        </template>
        
        <template v-else>
          <div class="preview-other">
            <el-icon class="file-icon"><document /></el-icon>
            <div class="file-info">
              <div class="file-name">{{ currentPreviewFile.name }}</div>
              <div class="file-size">{{ formatFileSize(currentPreviewFile.size) }}</div>
            </div>
          </div>
        </template>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import DGTMessage from '@/utils/message'
import { downloadFile } from '@/utils/util'
import { useI18n } from 'vue-i18n' 
const { t } = useI18n() 
import { useAppStore } from '@/pinia/appStore'
const appStore = useAppStore();
// import { 
//   UploadFilled, 
//   ZoomIn, 
//   Download, 
//   Delete, 
//   Document,
//   Plus
// } from '@element-plus/icons-vue'

// 组件属性
const props = defineProps({
  disabled: {
    type: Boolean,
    default: false
  },
  // 上传地址
  uploadUrl: {
    type: String,
    default: import.meta.env.VITE_API_BASE_URL + '/upload'
  },
  // 请求头
  headers: {
    type: Object,
    default: () => ({
      'Authorization': 'Bearer ' + localStorage.getItem('token')
    })
  },
  // 请求方法
  method: {
    type: String,
    default: 'post'
  },
  // 是否支持多文件上传
  multiple: {
    type: Boolean,
    default: false
  },
  // 上传时附带的额外参数
  data: {
    type: Object,
    default: () => ({
      //"note","笔记""workflow","工作流""video","视频""common","公共"
      "directory":"common"
    })
  },
  // 文件字段名
  fileFieldName: {
    type: String,
    default: 'file'
  },
  // 是否携带凭证信息
  withCredentials: {
    type: Boolean,
    default: false
  },
  // 是否显示已上传文件列表
  showFileList: {
    type: Boolean,
    default: true
  },
  // 接受的文件类型
  accept: {
    type: String,
    default: ''
  },
  // 最大允许上传文件数量
  limit: {
    type: Number,
    default: 0 // 0 表示不限制
  },
  // 已上传的文件列表
  modelValue: {
    type: Array,
    default: () => []
  },
  // 是否自动上传
  autoUpload: {
    type: Boolean,
    default: true
  },
  // 是否启用拖拽上传
  drag: {
    type: Boolean,
    default: false
  },
  // 文件列表的类型
  listType: {
    type: String,
    default: 'text', // text, picture, picture-card
    validator: (value) => ['text', 'picture', 'picture-card'].includes(value)
  },
  // 上传按钮文字
  buttonText: {
    type: String,
    default: '点击上传'
  },
  // 提示文字
  tip: {
    type: String,
    default: ''
  },
  // 最大文件大小 (MB)
  maxSize: {
    type: Number,
    default: 10 // 0 表示不限制
  },
  // 是否显示进度条
  showProgress: {
    type: Boolean,
    default: true
  },
  // 是否为头像上传模式（只显示头像预览，不显示上传按钮）
  isUploadAvatar: {
    type: Boolean,
    default: false
  }
})

// 组件事件
const emit = defineEmits([
  'update:modelValue', // 文件列表更新事件
  'before-upload', // 上传前事件
  'before-remove', // 删除前事件
  'success', // 上传成功事件
  'error', // 上传失败事件
  'progress', // 上传进度事件
  'change', // 文件状态改变事件
  'remove', // 文件移除事件
  'exceed', // 文件数量超出限制事件
  'preview', // 文件预览事件
  'download' // 文件下载事件
])

// 内部状态
const uploadRef = ref(null)
const fileList = ref([...props.modelValue])
const previewVisible = ref(false)
const currentPreviewFile = ref(null)
const currentPreviewContent = ref('')

// 计算属性
const uploadData = computed(() => props.data)
const previewTitle = computed(() => currentPreviewFile.value ? `预览：${currentPreviewFile.value.name}` : '文件预览')
// 添加一个标志位，防止循环更新
const isInnerUpdate = ref(false)
// 监听modelValue变化，同步到内部fileList
watch(() => props.modelValue, (newVal) => {
  // 如果是内部更新触发的，跳过
  if (isInnerUpdate.value) {
    isInnerUpdate.value = false;
    return;
  }
  if (newVal && newVal.length) {
    fileList.value = newVal.map(item => ({
      ...item,  // 完全保留接口返回的原始数据
      name: item.name || item.originalFileName || (item.url ? item.url.substring(item.url.lastIndexOf('/') + 1) : 'unknown'),
      url: item.url || item.fileUrl || item.path,
      status: item.status || 'success',
      uid: item.uid || Date.now() + Math.random()
    }));
  }
  // fileList.value = [...newVal]
}, { immediate: true })

// 监听fileList变化，同步到modelValue
watch(() => fileList.value, (newVal) => {
  // 设置内部更新标志
  isInnerUpdate.value = true
  emit('update:modelValue', [...newVal])
}, { deep: true })

// 上传前的校验
const handleBeforeUpload = (rawFile) => {
  // 文件大小校验
  if (props.maxSize > 0) {
    const maxSizeBytes = props.maxSize * 1024 * 1024
    if (rawFile.size > maxSizeBytes) {
      DGTMessage.error(`文件大小超出限制，最大允许 ${props.maxSize}MB`)
      emit('error', {
        message: `文件大小超出限制，最大允许 ${props.maxSize}MB`
      })
      return false
    }
  }
  // 文件类型校验
  if (props.accept) {
    // 解析accept字符串，支持MIME类型和文件扩展名
    const acceptTypes = props.accept.split(',').map(type => type.trim())
    let isAcceptable = false
    
    // 获取文件的MIME类型和扩展名
    const fileType = rawFile.type
    const fileName = rawFile.name
    const fileExt = fileName.substring(fileName.lastIndexOf('.')).toLowerCase()
    
    // 检查是否符合任何一个accept类型
    for (const acceptType of acceptTypes) {
      if (acceptType === '') continue
      
      // 检查MIME类型（如image/*、application/pdf）
      if (acceptType.includes('/')) {
        if (acceptType.endsWith('*')) {
          // 通配符类型，如image/*
          const mimePrefix = acceptType.substring(0, acceptType.indexOf('*'))
          if (fileType.startsWith(mimePrefix)) {
            isAcceptable = true
            break
          }
        } else {
          // 具体MIME类型，如application/pdf
          if (fileType === acceptType) {
            isAcceptable = true
            break
          }
        }
      } else if (acceptType.startsWith('.')) {
        // 检查文件扩展名（如.jpg、.png）
        if (fileExt === acceptType.toLowerCase()) {
          isAcceptable = true
          break
        }
      }
    }
    
    if (!isAcceptable) {
      DGTMessage.error(`${t('common.fileTypeNotAllow')} ${props.accept}`)
      emit('error', {
        message: `${t('common.fileTypeNotAllow')} ${props.accept}`
      })
      return false
    }
  }

  // 调用外部before-upload钩子
  return emit('before-upload', rawFile) !== false
}

// 上传成功处理
const handleSuccess = (response, rawFile, uploadedFiles) => {
  // 将上传成功的文件添加到fileList中
  // fileList.value.push({
  //   ...response,
  //   name: response.originalFileName || response.name,
  //   url: response.url,
  //   status: 'success',
  //   uid: rawFile.uid
  // })
  emit('success', response, rawFile, uploadedFiles)
}

// 上传失败处理
const handleError = (error, rawFile, uploadedFiles) => {
  DGTMessage.error(error.message || '文件上传失败')
  emit('error', error, rawFile, uploadedFiles)
}

// 上传进度处理
const handleProgress = (event, file, uploadedFiles) => {
  emit('progress', event, file, uploadedFiles)
}

// 文件状态改变处理
const handleChange = (file, newFileList) => {
  // 更新内部fileList
  fileList.value = newFileList.map(item => {
    // 如果文件已上传成功且有response，使用服务器返回的URL
    if (item.status === 'success' && item.response) {
      return {
        ...item.response,
        name: item.response.originalFileName || item.name,
        url: item.response.url,
        status: 'success',
        uid: item.uid
      }
    }
    return item
  })
  emit('change', file, fileList)
}

// 删除文件前的处理
const handleBeforeRemove = (file, fileList) => {
  return emit('before-remove', file, fileList) !== false
}

// 文件移除处理
const handleRemove = (file) => {
  console.log('移除文件:', file)
  // 从fileList中移除该文件
  // fileList.value = fileList.value.filter(f => f.url !== file.url)
  // 从fileList中移除该文件
  const index = fileList.value.findIndex(f => 
    f.uid === file.uid
  )
  console.log('index:', index,fileList.value)
  if (index > -1) {
    fileList.value.splice(index, 1)
  }
  emit('remove', file, fileList)
}

// 文件数量超出限制处理
const handleExceed = (files, fileList) => {
  DGTMessage.error(`文件数量超出限制，最多允许上传 ${props.limit} 个文件`)
  emit('exceed', files, fileList)
}

// 文件预览处理
const handlePreview = (file,index) => {
  console.log('预览文件:', file,index)
  currentPreviewFile.value = file
  
  // 图片文件直接预览
  if (isImageFile(file)) {
    previewVisible.value = true
    emit('preview', file)
    return
  }
  
  // 文本文件读取内容后预览
  if (isTextFile(file)) {
    if (file.url) {
      //浏览器下载
      downloadFile({url:file.url, fileName: file.name,t})

      // fetch(file.url)
      //   .then(response => response.text())
      //   .then(text => {
      //     currentPreviewContent.value = text
      //     previewVisible.value = true
      //     emit('preview', file)
      //   })
      //   .catch(error => {
      //     console.error('读取文件内容失败:', error)
      //     emit('error', error, file)
      //   })
    } else {
      previewVisible.value = true
      emit('preview', file)
    }
    return
  }
  
  // 其他文件类型
  previewVisible.value = true
  emit('preview', file)
}

// 文件下载处理
const handleDownload = (file) => {
  emit('download', file)
}

// 辅助方法：判断是否为图片文件
const isImageFile = (file) => {
  return file.type && file.type.startsWith('image/') || 
         /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.name)
}

// 辅助方法：判断是否为文本文件
const isTextFile = (file) => {
  return file.type && file.type.startsWith('text/') || 
         /\.(txt|json|yaml|yml|xml|html|htm|css|js|ts|md|markdown|zip|rar)$/i.test(file.name)
}

// 辅助方法：格式化文件大小
const formatFileSize = (size) => {
  if (size < 1024) {
    return `${size} B`
  } else if (size < 1024 * 1024) {
    return `${(size / 1024).toFixed(2)} KB`
  } else if (size < 1024 * 1024 * 1024) {
    return `${(size / (1024 * 1024)).toFixed(2)} MB`
  } else {
    return `${(size / (1024 * 1024 * 1024)).toFixed(2)} GB`
  }
}

// 暴露方法给父组件
defineExpose({
  // 手动上传文件
  submitUpload: () => uploadRef.value?.submit(),
  // 清除文件列表
  clearFiles: () => uploadRef.value?.clearFiles(),
  // 撤销上传请求
  abort: (file) => uploadRef.value?.abort(file),
  // 获取当前文件列表
  getFileList: () => [...fileList.value],
  // 手动添加文件到列表
  addFile: (file) => {
    fileList.value.push(file)
    return fileList.value
  },
  // 手动移除文件
  removeFile: (file) => {
    const index = fileList.value.findIndex(item => item.uid === file.uid)
    if (index > -1) {
      fileList.value.splice(index, 1)
    }
    return fileList.value
  }
});
</script>

<style lang="scss">
.file-uploader-container{
  &.hide-upload-btn{
    .el-upload--picture-card{
      display: none;
    }
  }
  &.is-upload-avatar{
    .el-upload--picture-card{
      border-color: transparent;
      height: 80px;
      width: 80px;
    }
    .el-upload-list__item{
      border-radius: 50%;
      height: 80px;
      width: 80px;
      .el-upload-list__item-status-label{
        display:none;
      }
    }
    .el-upload-list__item-thumbnail{
      object-fit: fill
    }
    .el-upload-list--picture-card .el-upload-list__item{
      margin: 0;
    }
  }
};
</style>

<style scoped lang="scss">
.file-uploader-container {
  width: 100%;
  
  .preview-container {
    width: 100%;
    min-height: 60vh;
    overflow: auto;
    
    .preview-image {
      width: 100%;
      height: auto;
      object-fit: contain;
    }
    
    .preview-text {
      width: 100%;
      padding: 10px;
      background-color: #f5f5f5;
      border-radius: 4px;
      font-family: monospace;
      white-space: pre-wrap;
    }
    
    .preview-other {
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 40px 0;
      
      .file-icon {
        font-size: 64px;
        color: #409eff;
        margin-right: 20px;
      }
      
      .file-info {
        text-align: left;
        
        .file-name {
          font-size: 16px;
          font-weight: 500;
          margin-bottom: 8px;
        }
        
        .file-size {
          font-size: 14px;
          color: #666;
        }
      }
    }
  }
}
</style>