<!--
 * @Author: LiZhiWei
 * @Date: 2025-04-24 15:23:24
 * @LastEditors: LiZhiWei
 * @LastEditTime: 2025-04-25 09:48:50
 * @Description: 
-->
<template>
  <div class="container">
    <div class="file-input-container">
      <div class="input-group">
        <el-select
          v-model="fileUrl"
          filterable
          allow-create
          default-first-option
          placeholder="请选择或输入文件预览地址"
          class="input-field"
        >
          <el-option
            v-for="item in urlOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" @click="loadFileFromUrl" :loading="loading"
          >预览</el-button
        >
      </div>

      <div class="upload-group">
        <el-upload
          action=""
          :auto-upload="false"
          :show-file-list="false"
          :on-change="handleFileChange"
        >
          <el-button type="primary">选择本地文件</el-button>
        </el-upload>
      </div>
    </div>

    <div class="preview-container" v-if="fileData.fileBuffer">
      <view-file :file="fileData" />
    </div>
    <div class="empty-tip" v-else>
      <el-icon class="empty-icon"><document /></el-icon>
      <p>请输入文件预览地址或上传本地文件</p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue"
import ViewFile from "@/components/view_file/index.vue"

type file = {
  filename: string 
  type: string
  fileBuffer: ArrayBuffer | null
}
// 文件数据对象
const fileData = ref<file>({
  filename: "", //文件名
  type: "", // 文件类型，可以是 pdf, docx, xlsx, pptx, image, text 等
  fileBuffer: null, // 文件缓冲区，实际使用时需要从后端获取或本地读取
})

const fileUrl = ref("")
const loading = ref(false)
const selectedFile = ref<any>(null)
const urlOptions = [
  {
    value:
      "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.pptx",
    label: "PPT示例文件",
  },
  {
    value:
      "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.docx",
    label: "Word示例文件",
  },
  {
    value:
      "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.pdf",
    label: "PDF示例文件",
  },
  {
    value:
      "https://501351981.github.io/vue-office/examples/dist/static/test-files/test.xlsx",
    label: "Excel示例文件",
  },
  {
    value:
      "https://fastly.picsum.photos/id/641/800/600.jpg?hmac=DJCZbdxrCoJPFV0jAsSIG1Ny0oc48zL3iqeMFqtKlD4",
    label: "图片示例文件",
  },
]

// 从URL加载文件
const loadFileFromUrl = async () => {
  if (!fileUrl.value) {
    ElMessage.warning("请输入文件预览地址")
    return
  }

  loading.value = true
  try {
    const response = await fetch(fileUrl.value)
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const buffer = await response.arrayBuffer()
    const contentType = response.headers.get("content-type") || ""
    const contentDisposition = response.headers.get("content-disposition") || ""

    // 尝试从响应头获取文件名
    let filename = ""
    const filenameMatch = contentDisposition.match(
      /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
    )
    if (filenameMatch && filenameMatch[1]) {
      filename = filenameMatch[1].replace(/['"]/g, "")
    } else {
      // 如果响应头中没有文件名，从URL中提取
      const urlParts = fileUrl.value.split("/")
      filename = urlParts[urlParts.length - 1].split("?")[0]
    }

    // 从文件名或内容类型确定文件类型
    let fileType = ""
    if (filename.includes(".")) {
      const ext = filename.split(".").pop()
      fileType = ext ? ext.toLowerCase() : ""
    } else if (contentType.includes("pdf")) {
      fileType = "pdf"
    } else if (contentType.includes("image")) {
      fileType = contentType.split("/")[1]
    } else if (contentType.includes("text")) {
      fileType = "text"
    }

    fileData.value = {
      filename: filename || "未知文件",
      type: fileType,
      fileBuffer: buffer,
    }
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : String(error)
    console.error("加载文件失败:", error)
    ElMessage.error("加载文件失败: " + message)
  } finally {
    loading.value = false
  }
}

// 处理本地文件上传
const handleFileChange = (file: any) => {
  if (!file) return

  selectedFile.value = file

  const reader = new FileReader()
  reader.onload = (e) => {
    const buffer = e.target?.result
    const filename = file.name
    const ext = filename.split(".").pop()
    const fileType = ext ? ext.toLowerCase() : ""

    if (!(buffer instanceof ArrayBuffer)) return

    fileData.value = {
      filename: filename,
      type: fileType,
      fileBuffer: buffer,
    }
  }
  reader.onerror = (e) => {
    console.error("读取文件失败:", e)
    ElMessage.error("读取文件失败")
  }

  reader.readAsArrayBuffer(file.raw)
}
</script>

<style scoped lang="less">
.container {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
}

.file-input-container {
  margin-bottom: 20px;
  background-color: #fff;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  display: flex;
  gap: 15px;
  .input-group {
    display: flex;
    align-items: center;
    .input-field {
      margin-right: 10px;
      width: 300px;
    }
  }

  .upload-group {
    display: flex;
    align-items: center;

    .file-name {
      margin-left: 10px;
      color: #606266;
      font-size: 14px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      max-width: 300px;
    }
  }
}

.preview-container {
  flex: 1;
  border-radius: 8px;
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;

  .file-info {
    padding: 12px 20px;
    border-bottom: 1px solid #ebeef5;
    display: flex;
    align-items: center;

    .file-title {
      font-size: 16px;
      font-weight: 500;
      color: #303133;
      margin-right: 10px;
    }

    .file-type {
      font-size: 12px;
      color: #909399;
      background-color: #f0f2f5;
      padding: 2px 6px;
      border-radius: 4px;
    }
  }
}

.empty-tip {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #909399;
  font-size: 16px;
  border: 1px dashed #d9d9d9;
  border-radius: 8px;
  background-color: #fff;

  .empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
    color: #c0c4cc;
  }

  p {
    margin: 0;
  }
}
</style>
