<template>
    <div>
      <el-dialog
        v-model="dialogFormVisible"
        :title="title"
        width="80%"
        :before-close="handleClose"
        class="file-preview-dialog"
      >
        <div class="preview-container">
          <!-- 加载状态 -->
          <div v-if="loading" class="loading-container">
            <el-icon class="is-loading" size="48">
              <Loading />
            </el-icon>  
            <p>{{ loadingText }}</p>
            <!-- <p v-if="convertTaskId" class="task-id">任务ID: {{ convertTaskId }}</p> -->
          </div>
  
          <!-- 转换状态 -->
          <div v-else-if="converting" class="loading-container">
            <el-icon class="is-loading" size="48">
              <Loading />
            </el-icon>  
            <p>{{ conversionMessage }}</p>
            <!-- <p class="task-id">任务ID: {{ convertTaskId }}</p> -->
          </div>
  
          <!-- 下载状态 -->
          <div v-else-if="downloading" class="loading-container">
            <el-icon class="is-loading" size="48">
              <Loading />
            </el-icon>  
            <p>正在下载文件，请稍候...</p>
            <p class="download-progress" v-if="downloadProgress > 0">
              下载进度: {{ downloadProgress }}%
            </p>
          </div>
  
          <!-- 错误状态 -->
          <div v-else-if="error" class="error-container">
            <el-icon size="48" color="#F56C6C">
              <CircleClose />
            </el-icon>
            <p>文件预览失败</p>
            <p class="error-message">{{ errorMessage }}</p>
            <el-button type="primary" @click="retryPreview">重试</el-button>
          </div>
  
          <!-- 文件预览内容 -->
          <div v-else class="file-content">
            <!-- 图片预览 -->
            <div v-if="isImage" class="image-preview">
              <img :src="previewUrl" :alt="fileName" @load="handleImageLoad" />
            </div>
  
            <!-- PDF预览 - 使用 vue-pdf-embed -->
            <div v-else-if="isPdf" class="pdf-preview">
              <div class="pdf-controls" v-if="pageCount > 0">
                <el-button-group>
                  <el-button :disabled="currentPage <= 1" @click="previousPage">
                    <el-icon><ArrowLeft /></el-icon>
                    上一页
                  </el-button>
                  <el-button>
                    {{ currentPage }} / {{ pageCount }}
                  </el-button>
                  <el-button :disabled="currentPage >= pageCount" @click="nextPage">
                    下一页
                    <el-icon><ArrowRight /></el-icon>
                  </el-button>
                </el-button-group> 
              </div>
              
              <div class="pdf-viewer-container">
                <VuePdfEmbed
                  :source="pdfSource"
                  :page="currentPage"
                  :scale="scale"
                  @loaded="handlePdfLoaded"
                  @rendered="handlePdfRendered"
                  @error="handlePdfError"
                  class="pdf-viewer"
                />
              </div>
            </div>
  
            <!-- 视频预览 -->
            <div v-else-if="isVideo" class="video-preview">
              <video controls :src="previewUrl" class="video-player">
                您的浏览器不支持视频播放
              </video>
            </div>
  
            <!-- 音频预览 -->
            <div v-else-if="isAudio" class="audio-preview">
              <audio controls :src="previewUrl" class="audio-player">
                您的浏览器不支持音频播放
              </audio>
            </div>
  
            <!-- 文本预览 -->
            <div v-else-if="isText" class="text-preview">
              <pre>{{ textContent }}</pre>
            </div>
  
            <!-- Office文档预览（转换后） -->
            <div v-else-if="isConvertedOffice" class="office-preview">
              <!-- 转换后的Office文件也是PDF，使用相同的PDF预览器 -->
              <div class="pdf-controls" v-if="pageCount > 0">
                <el-button-group>
                  <el-button :disabled="currentPage <= 1" @click="previousPage">
                    <el-icon><ArrowLeft /></el-icon>
                    上一页
                  </el-button>
                  <el-button>
                    {{ currentPage }} / {{ pageCount }}
                  </el-button>
                  <el-button :disabled="currentPage >= pageCount" @click="nextPage">
                    下一页
                    <el-icon><ArrowRight /></el-icon>
                  </el-button>
                </el-button-group>  
              </div>
              
              <div class="pdf-viewer-container">
                <VuePdfEmbed
                  :source="pdfSource"
                  :page="currentPage"
                  :scale="scale"
                  @loaded="handlePdfLoaded"
                  @rendered="handlePdfRendered"
                  @error="handlePdfError"
                  class="pdf-viewer"
                />
              </div>
            </div>
  
            <!-- 不支持预览的文件类型 -->
            <div v-else class="unsupported-preview">
              <el-icon size="64" color="#909399">
                <Document />
              </el-icon>
              <p>不支持在线预览此文件类型</p>
              <p class="file-name">{{ fileName }}</p>
            </div>
          </div>
        </div>
  
        <!-- 底部操作栏 -->
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="close">
              关闭
            </el-button>
          </div>
        </template>
      </el-dialog>
      <el-dialog
        v-model="dialogFileVisible"
        title="文件转换"
        width="50%"     
        class="file-preview-dialog"
      >
        <div class="preview-container">
            <div class="loading-container">
                <el-icon class="is-loading" size="48">
                <Loading />
                </el-icon>  
                <p>正在下载文件，请稍候...</p> 
            </div>
             
        </div>  
      </el-dialog>
    </div> 
</template>
  
<script setup>
import { ref, computed, getCurrentInstance, onUnmounted, nextTick, onMounted } from 'vue'
import { convertFileApi, getConvertStatusApi } from '@/api/conferencingRoom'
import { ElMessage ,ElMessageBox} from 'element-plus'
import { 
  Loading, 
  CircleClose, 
  Document, 
  ArrowLeft, 
  ArrowRight, 
} from '@element-plus/icons-vue'
import VuePdfEmbed from 'vue-pdf-embed'
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", "txt", "mp4", "mp3"],
  },
  roomId: {
    type: String,
    default: '',
  },
})

// 定义emits
const emit = defineEmits(['fetch-data'])

const { proxy } = getCurrentInstance()
const enumType = ["doc", "docx", "xls", "xlsx", "ppt", "pptx"]

// 响应式数据
const dialogFormVisible = ref(false)
const title = ref('')
const loading = ref(false)
const converting = ref(false)
const downloading = ref(false)
const downloadProgress = ref(0)
const loadingText = ref('正在加载...')
const conversionMessage = ref('正在转换文件...')
const error = ref(false)
const errorMessage = ref('')
const previewUrl = ref('')
const fileName = ref('')
const textContent = ref('')
const currentFileData = ref(null)
const convertTaskId = ref('')
const dialogFileVisible = ref(false)


// PDF相关状态
const pdfSource = ref('')
const currentPage = ref(1)
const pageCount = ref(0)
const scale = ref(1.0)
const pdfDocument = ref(null)

// MQTT相关
const isMqttConnected = ref(false)


// 计算属性
const isImage = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase()
  return ['png', 'jpg', 'jpeg', 'gif'].includes(ext)
})

const isPdf = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase() 
  return ext === 'pdf'
})

const isVideo = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase()
  return ['mp4'].includes(ext)
})

const isAudio = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase()
  return ['mp3'].includes(ext)
})

const isText = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase()
  return ext === 'txt'
})

const isOffice = computed(() => {
  const ext = fileName.value.split('.').pop().toLowerCase()
  return enumType.includes(ext)
})

const isConvertedOffice = computed(() => {
  return previewUrl.value && previewUrl.value.endsWith('.pdf') && isOffice.value
})

// 组件挂载时初始化MQTT连接
onMounted(async () => { 
})
emitter.on('subscribeToFileConversionStatusTopic',subscribeToFileConversionStatusTopic)
emitter.on('fileUploadStatus',fileUploadStatus)
emitter.on('subscribeToFilePreviewTopic',subscribeToFilePreviewTopic)
emitter.on('fileSuccess',fileSuccess)

function fileSuccess(){
    dialogFileVisible.value = true
}
//
function subscribeToFileConversionStatusTopic(data){
    try {
    const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid
    if (!userId) {
      console.error('用户ID不存在')
      return
    }  
    const topic = `xsynergy/room/${data.roomId}/file/${userId}/conversion_status` 
    mqttClient.subscribe(topic, handlePdfMessage)
    
  } catch (error) {
    console.error('订阅pdf转换事件失败:', error)
  }
}

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

//提交转换任务，但文件暂未转换完成
function fileUploadStatus(data){ 
    // console.log('文件上传成功mqtt消息')
}

// 初始化MQTT连接 pdf转换成功
async function initMqttConnection() {
  try {
    if (isMqttConnected.value) return 
    const clientId = `PdfConversion_${Date.now()}`
    await mqttClient.connect(clientId)
    isMqttConnected.value = true  
    // 订阅主题
    subscribeToPdfConversionTopic() 
  } catch (error) {
    console.error('MQTT连接失败:', error)
    ElMessage.error('文件转换服务连接失败')
  }
} 

function subscribeToPdfConversionTopic() {
  try {
    const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid
    if (!userId) {
      console.error('用户ID不存在')
      return
    }  
    const topic = `xsynergy/room/${props.roomId}/file/${userId}/conversion_status` 
    mqttClient.subscribe(topic, handlePdfMessage)
    
  } catch (error) {
    console.error('订阅pdf转换事件失败:', error)
  }
} 

function handleFileUploadMessage(payload, topic){
    try { 
        const messageStr = payload.toString()  
        const data = JSON.parse(messageStr)    
        // emitter.emit('fileUploadStatus') 
        const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid 
        if(dialogFileVisible.value){
            dialogFileVisible.value = false
        } 
        if(dialogFormVisible.value && userId != data.user_uid){ 
                // 显示确认对话框
            ElMessageBox.confirm(
                `用户${data.user_uid}上传了${data.file_name}文件，是否立即预览？`,
                '文件更新提示',
                {
                    confirmButtonText: '预览',
                    cancelButtonText: '取消',
                    type: 'warning',
                    closeOnClickModal: false,
                    closeOnPressEscape: false,
                    showClose: false
                }
            ).then(() => {
                // 用户点击"预览"
                resetPreviewState()
                getPreviewFileUrl(data)
                ElMessage({
                    message: '已切换到新文件预览',
                    type: 'success'
                })
            }).catch(() => {
                // 用户点击"取消"
                ElMessage({
                    message: '已取消预览新文件，继续查看当前文件',
                    type: 'info'
                })
            })
            // resetPreviewState()
            // getPreviewFileUrl(data)
        } else { 
            ElMessage({
                message: `用户${data.user_uid}上传了${data.file_name}文件`, 
                type: 'info', 
            })
            showEdit(data) 
        }
    } catch (error) {
        console.error('处理转换状态消息失败:', error)
        handleError('处理转换状态失败')
    }
}

// 新增重置预览状态的方法
function resetPreviewState() {
    loading.value = true
    converting.value = false
    downloading.value = false
    downloadProgress.value = 0
    error.value = false
    previewUrl.value = ''
    textContent.value = ''
    resetPdfState()
    
    // 强制重新渲染
    nextTick(() => {
        // 确保DOM更新
    })
}

function handlePdfMessage(payload, topic){ 
  try { 
    const messageStr = payload.toString()  
    const data = JSON.parse(messageStr)   
    switch (data.status) {
      case 'converting':  
        break 
      case 'completed':   
        getConvertedFile(data.task_id,data.room_uid)
        break  
      case 'failed': 
        break 
      default:
        console.warn('未知的转换状态:', data.status)
    }
  } catch (error) {
    console.error('处理转换状态消息失败:', error)
    handleError('处理转换状态失败')
  }
}

// 获取转换后的文件
const getConvertedFile = async (taskId,roomId) => { 
  try {
    if (!taskId) {
      throw new Error('任务ID不存在')
    }  
    const fileRes = await getConvertStatusApi(taskId,roomId)
  } catch (err) {
    console.error('获取转换文件失败:', err)
    handleError('获取转换文件失败', err)
  }
}

// 修改 getPreviewFileUrl 方法，确保状态正确更新
async function getPreviewFileUrl(file){ 
    fileName.value = file.file_name || file.source_url.split('/').pop()
    const fileExt = fileName.value.split('.').pop().toLowerCase()   
    try {
        // 根据文件类型处理转换后的文件
        if (fileExt === 'pdf' || enumType.includes(fileExt)) {
            // PDF和Office文档使用PDF预览器
            await loadPdfFile(file.preview_url || file.file_url)
        } else if (fileExt === 'txt') {
            // 文本文件
            await loadTextFile(file.preview_url || file.file_url)
        } else if (['png', 'jpg', 'jpeg', 'gif'].includes(fileExt)) {
            // 图片文件直接预览
            previewUrl.value = file.preview_url || file.file_url
            // 确保图片重新加载
            nextTick(() => {
                loading.value = false
            })
        } else if (fileExt === 'mp4') {
            // 视频文件
            previewUrl.value = file.preview_url || file.file_url
            nextTick(() => {
                loading.value = false
            })
        } else if (fileExt === 'mp3') {
            // 音频文件
            previewUrl.value = file.preview_url || file.file_url
            nextTick(() => {
                loading.value = false
            })
        } else {
            // 其他文件类型
            previewUrl.value = file.preview_url || file.file_url
            nextTick(() => {
                loading.value = false
            })
        }
    } catch (error) {
        console.error('加载预览文件失败:', error)
        handleError('加载预览文件失败', error)
    }
}
// 显示弹框
const showEdit = async (data) => { 
    // 重置状态
    resetPreviewState()
    title.value = '文件预览'
    dialogFormVisible.value = true
    currentFileData.value = data
    // fileName.value = data.file_name || data.source_url.split('/').pop()
    
    await getPreviewFileUrl(data)
}

// 加载PDF文件
const loadPdfFile = async (fileUrl) => {
    try { 
        loading.value = false
        downloading.value = true
        downloadProgress.value = 0 
        
        const response = await fetch(fileUrl)
        if (!response.ok) {
            throw new Error('文件下载失败')
        } 
        
        const contentLength = response.headers.get('content-length')
        const total = parseInt(contentLength, 10)
        let loaded = 0 
        const reader = response.body.getReader()
        const chunks = [] 
        
        while (true) {
            const { done, value } = await reader.read() 
            if (done) break 
            chunks.push(value)
            loaded += value.length 
            if (total) {
                downloadProgress.value = Math.round((loaded / total) * 100)
            }
        }
        
        const blob = new Blob(chunks)
        const blobUrl = URL.createObjectURL(blob) 
        
        // 先清理之前的URL
        if (pdfSource.value) {
            URL.revokeObjectURL(pdfSource.value)
        }
        
        previewUrl.value = fileUrl
        pdfSource.value = blobUrl 
        
        // 重置PDF状态
        currentPage.value = 1
        pageCount.value = 0
        
        downloading.value = false
        downloadProgress.value = 0  
        
    } catch (err) {
        downloading.value = false
        downloadProgress.value = 0
        handleError('PDF文件下载失败', err)
    }
}

// 加载文本文件
const loadTextFile = async (fileUrl) => {
  try {
    const response = await fetch(fileUrl)
    if (!response.ok) throw new Error('无法加载文本文件')
    const text = await response.text()
    textContent.value = text
    loading.value = false
  } catch (err) {
    handleError('文本文件加载失败', err)
  }
}

// 上传文件获取office获取pdf文件
async function getFilePdf(fileUrl) {
  try {
    loadingText.value = '正在转换文件...'
    const res = await convertFileApi({ file_url: fileUrl },props.roomId) 
    if (res.meta.code !== 200) {
      throw new Error(res.meta.msg || '文件转换失败')
    }
    convertTaskId.value = res.data.task_id 
    // 等待MQTT消息，不进行轮询
    loading.value = false
    converting.value = true
    conversionMessage.value = '已提交转换任务，等待处理...'
    
  } catch (err) {
    handleError('文件转换失败', err)
  }
}

// PDF相关方法
const handlePdfLoaded = (data) => { 
  pageCount.value = data.numPages
  pdfDocument.value = data
  loading.value = false
  converting.value = false
}

const handlePdfRendered = () => {
//   console.log('PDF页面渲染完成')
}

const handlePdfError = (error) => {
  console.error('PDF加载错误:', error)
  handleError('PDF文件加载失败', error)
}

const previousPage = () => {
  if (currentPage.value > 1) {
    currentPage.value--
  }
}

const nextPage = () => {
  if (currentPage.value < pageCount.value) {
    currentPage.value++
  }
}

const resetPdfState = () => {
  pdfSource.value = ''
  currentPage.value = 1
  pageCount.value = 0
  scale.value = 1.0
  pdfDocument.value = null
}

// 处理图片加载完成
const handleImageLoad = () => {
  loading.value = false
}

// 处理错误
const handleError = (message, error) => { 
  error.value = true
  errorMessage.value = message
  loading.value = false
  converting.value = false
  downloading.value = false
  downloadProgress.value = 0
  ElMessage.error(message)
}

// 重试预览
const retryPreview = () => {
  if (currentFileData.value) {
    showEdit(currentFileData.value)
  }
}

// 关闭按钮点击事件
const close = () => {
  dialogFormVisible.value = false
  resetState()
}

// 处理对话框关闭
const handleClose = (done) => {
  close() 
}

// 重置状态
const resetState = () => { 
  loading.value = false
  converting.value = false
  downloading.value = false
  downloadProgress.value = 0
  error.value = false
  previewUrl.value = ''
  textContent.value = ''
  currentFileData.value = null
  convertTaskId.value = ''
  resetPdfState()
}

// 组件卸载时清理
onUnmounted(() => {
  // 可以在这里取消特定主题的订阅，但不断开连接
//   const userId = JSON.parse(sessionStorage.getItem('userData'))?.uid
//   if (userId) {
//     const topic = `xsynergy/room/${props.roomId}/file/${userId}/conversion_status`
//     mqttClient.unsubscribe(topic, handlePdfMessage)
//   }
})

// 暴露方法给父组件
defineExpose({
  showEdit, 
  close, 
})
</script>
  
  <style lang="scss" scoped>
  .file-preview-dialog {
    .preview-container {
      min-height: 400px;
      display: flex;
      align-items: center;
      justify-content: center;
      
      .loading-container, .error-container {
        text-align: center;
        padding: 40px 0;
        
        p {
          margin-top: 16px;
          color: #606266;
        }
        
        .error-message {
          font-size: 14px;
          color: #F56C6C;
          margin-top: 8px;
        }
        
        .download-progress {
          font-size: 14px;
          color: #409EFF;
          margin-top: 8px;
        }
      }
      
      .file-content {
        width: 100%;
        height: 100%;
        
        .image-preview {
          text-align: center;
          
          img {
            max-width: 100%;
            max-height: 70vh;
            object-fit: contain;
          }
        }
        
        .pdf-preview, .office-preview {
          .pdf-controls {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-bottom: 16px;
            padding: 8px;
            background: #f5f5f5;
            border-radius: 4px;
            flex-wrap: wrap;
            gap: 8px;
          }
          
          .pdf-viewer-container {
            height: 70vh;
            overflow: auto;
            border: 1px solid #e0e0e0;
            border-radius: 4px;
            background: #f9f9f9;
            
            .pdf-viewer {
              width: 100%;
              min-height: 100%;
              display: flex;
              justify-content: center;
              
              :deep(.vue-pdf-embed) {
                text-align: center;
              }
              
              :deep(canvas) {
                max-width: 100%;
                height: auto;
              }
            }
          }
        }
        
        .video-preview {
          text-align: center;
          
          .video-player {
            max-width: 100%;
            max-height: 70vh;
          }
        }
        
        .audio-preview {
          text-align: center;
          padding: 40px 0;
          
          .audio-player {
            width: 80%;
          }
        }
        
        .text-preview {
          height: 70vh;
          overflow: auto;
          background: #f5f5f5;
          padding: 16px;
          border-radius: 4px;
          
          pre {
            white-space: pre-wrap;
            word-wrap: break-word;
            margin: 0;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 14px;
            line-height: 1.5;
          }
        }
        
        .unsupported-preview {
          text-align: center;
          padding: 40px 0;
          
          p {
            margin-top: 16px;
            color: #606266;
          }
          
          .file-name {
            font-size: 14px;
            color: #909399;
            margin-top: 8px;
          }
        }
      }
    }
    
    .dialog-footer {
      display: flex;
      justify-content: space-between;
    }
  }
  
  @media (max-width: 768px) {
    .file-preview-dialog {
      width: 95% !important;
      
      .preview-container {
        min-height: 300px;
        
        .file-content {
          .pdf-preview, .office-preview {
            .pdf-viewer-container {
              height: 50vh;
            }
          }
          
          .text-preview {
            height: 50vh;
          }
        }
      }
      
      .pdf-controls {
        flex-direction: column;
        gap: 8px;
        
        .el-button-group {
          width: 100%;
          display: flex;
          
          .el-button {
            flex: 1;
            font-size: 12px;
            padding: 8px 4px;
          }
        }
      }
    }
  }
  </style>