<template>
  <div v-if="!pathError">
    <!-- 文档预览 -->
    <div v-if="showImagePreview === 1" 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-if="showImagePreview === 2" class="image-preview-container">
      <!-- 图片操作工具栏 -->
      <div class="image-toolbar">
        <a-button-group class="custom-btn-group">
          <a-tooltip title="放大图片">
            <a-button @click="zoomIn" icon="zoom-in"></a-button>
          </a-tooltip>
          <a-tooltip title="缩小图片">
            <a-button @click="zoomOut" icon="zoom-out"></a-button>
          </a-tooltip>
          <a-tooltip title="重置大小和旋转">
            <a-button @click="resetImage" icon="redo"></a-button>
          </a-tooltip>
          <a-tooltip title="顺时针旋转90°">
            <a-button @click="rotateImage" icon="sync"></a-button>
          </a-tooltip>
        </a-button-group>
      </div>

      <!-- 预览图片容器 -->
      <div
        class="image-preview-wrapper"
        @wheel.prevent="handleMouseWheel"
        @mousedown="handleMouseDown"
        @mousemove.passive="handleMouseMove"
        @mouseup="handleMouseUp"
        @mouseleave="handleMouseUp"
        :style="{ cursor: isDragging ? 'grabbing' : (scale > 1 ? 'grab' : 'zoom-in') }"
      >
        <img
          :src="previewImageSrc"
          alt="preview image"
          class="preview-image"
          :style="{
            transform: `translate(${x}px, ${y}px) scale(${scale}) rotate(${rotate}deg)`,
            transformOrigin: 'center center'
          }"
        />
      </div>
    </div>

    <!-- 视频预览 -->
    <div v-if="showImagePreview === 3" style="text-align: center">
      <video-player
        class="video-player vjs-custom-skin"
        ref="videoPlayer"
        :playsinline="true"
        :options="playerOptions">
      </video-player>
    </div>
  </div>
  <a-empty v-else description="文件路径为空" />
</template>

<script>
import { Base64 } from 'js-base64'
import 'video.js/dist/video-js.css'
import 'videojs-contrib-hls'
import { videoPlayer } from 'vue-video-player'
import { getConfigByNameAsync } from '@vue2-client/services/api/common'
import { mapState } from 'vuex'

export default {
  name: 'FilePreview',
  components: {
    videoPlayer
  },
  props: {
    path: {
      type: String,
      required: true
    },
  },
  data () {
    return {
      previewDocService: 'http://aote-office.8866.org:8406',
      fileServer: 'http://aote-office.8866.org:32510/onlinePreview?url=',
      // 文档预览
      previewDocLoading: true,
      previewDocUrl: '',
      // 图片预览
      showImagePreview: 1,
      previewImageSrc: '',
      // 图片操作参数（核心）
      scale: 1, // 缩放比例（默认1倍）
      rotate: 0, // 旋转角度（默认0°）
      scaleStep: 0.1, // 每次缩放步长（按钮/滚轮）
      maxScale: 3, // 最大缩放倍数
      minScale: 0.2, // 最小缩放倍数
      // 拖动相关参数（优化版）
      x: 0, // 水平偏移
      y: 0, // 垂直偏移
      startX: 0, // 鼠标按下时的X坐标
      startY: 0, // 鼠标按下时的Y坐标
      startOffsetX: 0, // 按下时的水平偏移
      startOffsetY: 0, // 按下时的垂直偏移
      isDragging: false, // 是否正在拖动
      // 视频
      previewVideoSrc: '',
      // 路径是否为空
      pathError: false,
      playerOptions: {
        playbackRates: [0.5, 1.0, 1.5, 2.0],
        autoplay: false,
        muted: false,
        loop: false,
        preload: 'auto',
        language: 'zh-CN',
        aspectRatio: '16:9',
        fluid: true,
        sources: [{
          type: '',
          src: ''
        }],
        poster: '',
        notSupportedMessage: '此视频暂无法播放，请稍后再试',
        controlBar: {
          timeDivider: true,
          durationDisplay: true,
          remainingTimeDisplay: false,
          fullscreenToggle: true
        }
      }
    }
  },
  computed: {
    ...mapState('setting', ['compatible'])
  },
  watch: {
    // 路径改变时刷新预览
    path: {
      immediate: true,
      handler () {
        this.preview()
      }
    }
  },
  mounted () {
    this.preview()
  },
  methods: {
    preview () {
      if (this.compatible === 'OA') {
        this.fileServer = 'http://aote-office.8866.org:8406'
        this.previewDocService = 'http://aote-office.8866.org:32510/onlinePreview?url='
        this.previewGen()
        return
      }
      getConfigByNameAsync('previewDocServiceConfig').then(res => {
        if (!res.fileServer) {
          this.$message.error('文件预览服务配置错误')
          return
        } else {
          this.previewDocService = res.previewDocService
          this.fileServer = res.fileServer
        }
        this.previewGen()
      })
    },
    previewGen () {
      // 重置所有图片操作参数
      this.scale = 1
      this.rotate = 0
      this.x = 0
      this.y = 0
      this.isDragging = false

      if (!this.path) {
        this.pathError = true
        return
      }
      this.pathError = false
      if (this.isImage()) {
        this.previewImageSrc = this.path
        this.showImagePreview = 2
      } else if (this.isVideo()) {
        this.playerOptions.sources[0].type = 'video/' + this.path.substring(this.path.lastIndexOf('.') + 1)
        this.playerOptions.sources[0].src = this.path
        this.showImagePreview = 3
      } else {
        const previewDocUrl = this.previewDocService + encodeURIComponent(Base64.encode(this.fileServer + this.path))
        if (this.previewDocUrl !== previewDocUrl) {
          this.previewDocLoading = true
          this.previewDocUrl = previewDocUrl
        }
        this.showImagePreview = 1
      }
    },
    // 判断是否为图片
    isImage () {
      const index = this.path.lastIndexOf('.')
      if (index === -1) return false
      const suffix = this.path.substr(index + 1).toLowerCase()
      return IMAGE_SUFFIX_ARRAY.includes(suffix)
    },
    // 判断是否为视频
    isVideo () {
      const index = this.path.lastIndexOf('.')
      if (index === -1) return false
      const suffix = this.path.substr(index + 1).toLowerCase()
      return VIDEO_SUFFIX_ARRAY.includes(suffix)
    },

    zoomIn () {
      if (this.scale < this.maxScale) {
        this.scale += this.scaleStep
      }
    },
    zoomOut () {
      if (this.scale > this.minScale) {
        this.scale -= this.scaleStep
      }
    },
    resetImage () {
      this.scale = 1
      this.rotate = 0
      this.x = 0
      this.y = 0
      this.isDragging = false
    },
    rotateImage () {
      this.rotate += 90
      if (this.rotate >= 360) this.rotate = 0
    },
    handleMouseWheel (e) {
      const delta = e.deltaY > 0 ? -this.scaleStep : this.scaleStep
      const newScale = this.scale + delta
      if (newScale >= this.minScale && newScale <= this.maxScale) {
        this.scale = newScale
      }
    },

    handleMouseDown (e) {
      if (this.scale <= 1) return
      this.isDragging = true
      this.startX = e.pageX
      this.startY = e.pageY
      this.startOffsetX = this.x
      this.startOffsetY = this.y
      e.preventDefault()
    },
    handleMouseMove (e) {
      if (!this.isDragging) return
      const dx = e.pageX - this.startX
      const dy = e.pageY - this.startY
      this.x = this.startOffsetX + dx
      this.y = this.startOffsetY + dy
    },
    handleMouseUp () {
      this.isDragging = false
    }
  }
}

// 图片后缀
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']
</script>

<style scoped>
.preview-doc-container {
  height: calc(100vh - 60px);
  padding-top: 20px;
}

.image-preview-container {
  width: 100%;
  height: calc(100vh - 60px);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px;
  box-sizing: border-box;
}


.image-toolbar {
  margin-bottom: 16px;
  z-index: 10;
}

.custom-btn-group {
  --btn-gap: 5px;
}

:deep(.custom-btn-group .ant-btn) {
  margin: 0 var(--btn-gap);
  border-radius: 4px !important;
}
:deep(.custom-btn-group .ant-btn:first-child) {
  margin-left: 0;
}
:deep(.custom-btn-group .ant-btn:last-child) {
  margin-right: 0;
}

.image-preview-wrapper {
  flex: 1;
  width: 100%;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  user-select: none;
  -webkit-user-drag: none;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  will-change: transform;
  backface-visibility: hidden;
  perspective: 1000px;
  transition: none;
  user-select: none;
  pointer-events: none;
  -webkit-user-drag: none;
}

:deep(.ant-tooltip) {
  z-index: 9999 !important;
}
</style>
