<script setup lang="ts">
import { getConfigByNameAsync } from '@af-mobile-client-vue3/services/api/common'
import { Base64 } from 'js-base64'
import { ref } from 'vue'

interface FilePreviewInitOptions {
  /** 预览文件完整路径（含后缀） */
  path: string
}

const IMAGE_SUFFIX_ARRAY = ['xbm', 'tif', 'pjp', 'svgz', 'jpg', 'jpeg', 'ico', 'tiff', 'gif', 'svg', 'jfif', 'webp', 'png', 'bmp', 'pjpeg', 'avif']
const VIDEO_SUFFIX_ARRAY = ['avi', 'wmv', 'mpeg', 'mp4', 'm4v', 'mov', 'asf', 'flv', 'f4v', 'rmvb', 'rm', '3gp', 'vob']

const previewDocService = ref('')
const fileServer = ref('')
const previewDocLoading = ref(true)
const previewDocUrl = ref('')
const previewMode = ref<'http' | 'doc' | 'image' | 'video'>('doc')
const previewImageSrc = ref('')
const previewVideoSrc = ref('')
const pathError = ref(false)

async function preview(path: string) {
  if (!path) {
    pathError.value = true
    return
  }
  pathError.value = false

  try {
    const res: any = await getConfigByNameAsync('previewDocServiceConfig')
    if (!res?.fileServer)
      throw new Error('文件预览服务配置错误')
    previewDocService.value = res.previewDocService
    fileServer.value = res.fileServer
  }
  catch (error) {
    console.warn('获取文件预览服务配置失败，使用默认配置', error)
  }
  previewGen(path)
}

function previewGen(path: string) {
  previewDocLoading.value = true
  if (isImage(path)) {
    previewImageSrc.value = path
    previewMode.value = 'image'
    return
  }

  if (isVideo(path)) {
    previewVideoSrc.value = path
    previewMode.value = 'video'
    return
  }
  if (isHttp(path)) {
    previewMode.value = 'doc'
    const previewUrl = `${previewDocService.value}${encodeURIComponent(Base64.encode(`${path}`))}`
    if (previewDocUrl.value !== previewUrl) {
      previewDocLoading.value = true
      previewDocUrl.value = previewUrl
    }
    else {
      previewDocLoading.value = false
    }
    return
  }

  previewMode.value = 'doc'
  const previewUrl = `${previewDocService.value}${encodeURIComponent(Base64.encode(`${fileServer.value}${path}`))}`
  if (previewDocUrl.value !== previewUrl) {
    previewDocLoading.value = true
    previewDocUrl.value = previewUrl
  }
  else {
    previewDocLoading.value = false
  }
}

function isImage(path: string) {
  const suffix = path.toLowerCase().split('.').pop()
  return suffix ? IMAGE_SUFFIX_ARRAY.includes(suffix) : false
}

function isVideo(path: string) {
  const suffix = path.toLowerCase().split('.').pop()
  return suffix ? VIDEO_SUFFIX_ARRAY.includes(suffix) : false
}

function isHttp(path: string) {
  return path.startsWith('http://') || path.startsWith('https://')
}

async function init(options: FilePreviewInitOptions) {
  await preview(options.path)
}

defineExpose({
  init,
})
</script>

<template>
  <div v-if="!pathError">
    <div v-if="previewMode === 'doc'" class="preview-doc-container">
      <a-spin size="large" :spinning="previewDocLoading" />
      <iframe
        v-show="!previewDocLoading"
        :src="previewDocUrl"
        width="100%"
        height="100%"
        frameborder="0"
        @load="previewDocLoading = false"
      />
    </div>
    <div v-else-if="previewMode === 'image'" class="preview-image-wrapper">
      <img :src="previewImageSrc" alt="image" class="preview-image">
    </div>
    <div v-else-if="previewMode === 'video'" class="preview-video-wrapper">
      <video
        class="preview-video"
        controls
        :src="previewVideoSrc"
      />
    </div>
  </div>
  <a-empty v-else description="文件路径为空" />
</template>

<style scoped>
.preview-doc-container {
  height: 100%;
}

.preview-image-wrapper,
.preview-video-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  background: #000000;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
}

.preview-video {
  width: 100%;
  max-height: 100%;
  border: none;
  background: #000;
}
</style>
