<template>
    <div>
      <el-dialog
        v-model="dialogFormVisible"
        :title="title"
        width="403px"
        @close="close" 
      >
        <el-upload
          ref="uploadRef" 
          :accept="acceptString"
          :show-file-list="false"
          :limit="999"
          style="width: 100%; text-align: center"
          :before-upload="handleBeforeUpload" 
        >
          <template #trigger>
            <el-button 
              type="primary" 
              class="el-button-custom-css blue-css"
              :loading="uploadLoading" 
              :disabled="uploadLoading"
            >
              {{ uploadLoading ? '上传中...' : '上传文件' }}
            </el-button>
          </template>
        </el-upload>
        <div style="margin-top: 20px">
          请上传格式为:
          <b style="color: #f56c6c">
            {{ acceptString }}
          </b>
          的文件
        </div>
      </el-dialog>
    </div>
</template>
  
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import axios from 'axios'
import { getUploadTokenApi, uploadFileApi,convertFileApi } from '@/api/conferencingRoom'
import { calculateFileSHA1 } from '@/views/conferencingRoom/business/index.js'
import { ElMessage, ElMessageBox } from 'element-plus'
import { mqttClient } from "@/utils/mqtt.js"; 
import { emitter } from "@/utils/bus.js"; 
// 定义props
const props = defineProps({
  fileType: {
    type: Array,
    default: () => ["pdf", "png", "jpg", "jpeg", "gif", "doc", "docx", "xls", "xlsx", "ppt", "pptx"],
  },
  roomId: {
    type: String,
    default: '',
  },
})

// 定义emits
const emit = defineEmits(['upload-success'])

const { proxy } = getCurrentInstance()

// 响应式数据
const dialogFormVisible = ref(false)
const title = ref('')
const fileList = ref([])
const fileIds = ref([])
const uploadRef = ref(null)
const showList = ref(true)
const saveLoading = ref(false) 

const uploadToken = ref('')
const fileUrl = ref('')
const currentUploadFile = ref(null) // 存储当前要上传的文件
const uploadLoading = ref(false) // 上传loading状态

const roomId = ref()
const uploaderInfo = ref('')

// 计算属性：将文件类型数组转换为accept字符串
const acceptString = computed(() => {
  return props.fileType.map(type => `.${type}`).join(', ')
})

emitter.on('subscribeToFileUploadTopic',subscribeToFileUploadTopic)


function subscribeToFileUploadTopic(data){  
    try {  
        // 订阅文件上传状态主题  
        roomId.value = data.roomId
        const topic = `xsynergy/room/${data.roomId}/file/upload` 
        mqttClient.subscribe(topic, handleFileUploadMessage) 
  } catch (error) {
        console.error('订阅文件上传事件失败:', error)
  }
}

//订阅文件上传状态主题 
function handleFileUploadMessage(payload, topic){
    try { 
    const messageStr = payload.toString()  
    const data = JSON.parse(messageStr)  
    emitter.emit('fileUploadStatus',data)
    emit('upload-success')
  } catch (error) {
    console.error('文件长传状态消息失败:', error)  
  }
}

// 上传前校检格式和大小
const handleBeforeUpload = async (file) => {
  // 如果正在上传中，阻止新文件上传
  if (uploadLoading.value) {
    ElMessage.warning('文件正在上传中，请稍候...')
    return false
  }

  // 获取文件扩展名
  const fileExtension = file.name.toLowerCase().slice(((file.name.lastIndexOf(".") - 1) >>> 0) + 2)
  // 校验文件格式
  if (!props.fileType.includes(fileExtension)) {
    ElMessage.error(`文件格式不支持，请上传 ${acceptString.value} 格式的文件`)  
    return false
  }
  
  // 校检文件大小
  const isLt = file.size / 1024 / 1024 < 50
  if (!isLt) {
    ElMessage.error(`上传文件大小不能超过 50 MB!`) 
    return false
  } 
  
  // 开始上传，设置loading状态
  uploadLoading.value = true
  
  try {
    // 保存当前文件引用
    currentUploadFile.value = file
    
    // 计算文件SHA1
    const sha1 = await calculateFileSHA1(file)  
    
    // 获取上传token
    const res = await getUploadTokenApi({
      service: props.roomId,
      hash: sha1,
      ext: fileExtension,
    })
    
    if(res.meta.code != 200){
      ElMessage.error(res.meta.msg)
      uploadLoading.value = false // 出错时取消loading
      return false
    }
    
    if(res.data.exists){
      // 文件已存在，直接获取文件URL
      fileUrl.value = res.data.fileUrl 
      ElMessage.info('文件已存在，无需重复上传')
    //   dialogFormVisible.value = false
      uploadLoading.value = false
    } else {
      // 文件不存在，获取token并执行上传
      uploadToken.value = res.data.token
      // 执行上传操作
      await handleHttpRequest(file)
    }
    
  } catch (error) {
    console.error('上传过程出错:', error)
    ElMessage.error('上传过程出错，请重试')
    uploadLoading.value = false // 出错时取消loading
    return false
  }
  
  return false // 阻止默认上传行为，因为我们使用自定义上传
}

// 自定义上传
const handleHttpRequest = async (file) => {
  if (!uploadToken.value) {
    ElMessage.error('上传凭证不存在')
    uploadLoading.value = false // 取消loading
    return false
  } 
  let params = new FormData()
  params.append('file', file) 
  
  try {
    const res = await uploadFileApi(uploadToken.value, params)
    if(res.meta.code != 200){
      ElMessage.error(res.meta.msg)
      uploadLoading.value = false // 出错时取消loading
      return false
    }  
    fileUrl.value = res.data.fileUrl 
    getFileTaskId(res.data.fileUrl)
    ElMessage.success('文件上传成功')
    // publishFileUploadData(file);  
     
    // 上传成功，取消loading
    uploadLoading.value = false
    dialogFormVisible.value = false

    emitter.emit('fileSuccess')
    return true
  } catch (error) {
    console.error('上传文件失败:', error)
    ElMessage.error('上传文件失败')
    uploadLoading.value = false // 出错时取消loading
    return false
  } 
}
async function getFileTaskId(fileUrl) {
  try { 
    const res = await convertFileApi({ file_url: fileUrl },props.roomId) 
    if (res.meta.code !== 200) {
      throw new Error(res.meta.msg || '文件转换失败')
    }  
  } catch (err) { 
    ElMessage.error('文件转换失败')
  }
}

function publishFileUploadData(fileData) {
    try { 
        const message = { 
            uploaderName: uploaderInfo.value?.name || '', 
            uploaderUid: uploaderInfo.value?.uid || '', 
            fileName: fileData.name, 
            fileUrl: fileUrl.value, 
            roomId: roomId.value, 
            timestamp: Date.now(), 
        }; 
        mqttClient.publish(`xSynergy/File/Upload/${roomId.value}`, message);
    } catch (error) {
        console.error('发布文件数据失败:', error);
    }
}

// 上传前校检格式和大小
const beforeUploadser = (file) => {
  return false
}

// 显示弹框
const showEdit = () => {
  title.value = '上传文件'
  dialogFormVisible.value = true
  uploaderInfo.value = JSON.parse(sessionStorage.getItem('userData'))
}

// 关闭按钮点击事件
const close = () => {
  fileList.value = []
  currentUploadFile.value = null
  uploadToken.value = ''
  fileUrl.value = ''
  uploadLoading.value = false // 关闭时重置loading状态
  dialogFormVisible.value = false
}

// 保存按钮点击事件
const save = () => {
  close()
}

// 暴露方法给父组件
defineExpose({
  showEdit, 
  close,
  save
})
</script>
  
<style lang="scss">
.avatar-uploader {
  .el-upload {
    width: 345px;
    height: 180px;
  }
  .el-upload-list__item-thumbnail {
    height: 180px;
  }
}
@media (max-width: 765px) {
  .el-dialog {
    width: 80% !important;
  }
}
</style>