<template>
  <!-- 全屏预览容器 -->
  <div v-if="visible" class="fullscreen-preview-wrapper">
    <!-- 图片预览区域（占满全屏） -->
    <div
      class="image-preview-container"
      @wheel="handleWheel"
      @mousedown="startDrag"
      ref="previewContainer"
      :class="{ dragging: isDragging }"
      tabindex="0"
      @keydown="handleKeydown"
    >
      <!-- 加载中状态 -->
      <div v-if="loading" class="loading-wrapper">
        <a-spin size="large" tip="图片加载中..." />
      </div>

      <!-- 加载失败状态 -->
      <div v-else-if="loadError" class="error-wrapper">
        <a-icon type="picture" class="error-icon" />
        <p>图片加载失败</p>
        <a-button type="link" @click="retryLoad">点击重试</a-button>
      </div>

      <!-- 图片内容 -->
      <div v-show="!loading && !loadError" class="image-wrapper" :style="wrapperStyle">
        <img
          :src="effectiveImageUrl"
          alt="预览图片"
          class="preview-image"
          :style="imageStyle"
          ref="previewImage"
          @load="onImageLoad"
          @error="onImageError"
        />
      </div>
    </div>

    <!-- 底部工具栏 -->
    <div class="preview-toolbar bottom-toolbar" @wheel.prevent.stop>
      <div class="toolbar-content">
        <a-tooltip title="放大">
          <a-button type="primary" icon="zoom-in" @click="zoomIn" size="small" class="toolbar-btn" />
        </a-tooltip>
        <a-tooltip title="缩小">
          <a-button type="primary" icon="zoom-out" @click="zoomOut" size="small" class="toolbar-btn" />
        </a-tooltip>
        <a-tooltip title="重置">
          <a-button type="primary" icon="reload" @click="resetImageTransform" size="small" class="toolbar-btn" />
        </a-tooltip>
        <a-tooltip title="向左旋转">
          <a-button type="primary" icon="undo" @click="rotateLeft" size="small" class="toolbar-btn" />
        </a-tooltip>
        <a-tooltip title="向右旋转">
          <a-button type="primary" icon="redo" @click="rotateRight" size="small" class="toolbar-btn" />
        </a-tooltip>
        <a-tooltip title="下载图片">
          <a-button
            type="primary"
            icon="download"
            @click="downloadImage"
            size="small"
            class="toolbar-btn"
            :loading="downloading"
          />
        </a-tooltip>
        <div class="toolbar-divider"></div>
        <a-tooltip title="关闭">
          <a-button type="primary" icon="close" @click="handleClose" size="small" class="toolbar-btn close-btn" />
        </a-tooltip>
      </div>
    </div>
  </div>
</template>

<script>
import { createFileImageService } from '@vue2-client/utils/fileImageService'

// 缩放配置常量
const ZOOM_CONFIG = {
  MIN: 0.1, // 最小缩放比例 10%
  MAX: 3, // 最大缩放比例 300%
  STEP: 0.25 // 统一缩放步长
}

// 旋转配置常量
const ROTATE_STEP = 90

export default {
  name: 'ImagePreviewModal',
  props: {
    // 是否显示预览模态框
    visible: {
      type: Boolean,
      default: false
    },
    // 图片URL（直接传入时使用，优先级高于 fileId + serviceName）
    imageUrl: {
      type: String,
      default: ''
    },
    // 文件ID（配合 serviceName 使用，内部自动加载图片 URL）
    fileId: {
      type: [String, Number, Object],
      default: null
    },
    // 服务名（如 'af-safecheck'），与 fileId 配合使用
    serviceName: {
      type: String,
      default: ''
    },
    // 图片名称（用于下载）
    imageName: {
      type: String,
      default: 'preview_image'
    }
  },
  data() {
    return {
      scale: 1, // 缩放比例
      rotate: 0, // 旋转角度
      isDragging: false, // 是否正在拖动
      dragStartX: 0, // 拖动起始X坐标
      dragStartY: 0, // 拖动起始Y坐标
      translateX: 0, // X轴平移距离
      translateY: 0, // Y轴平移距离
      loading: true, // 图片加载中
      loadError: false, // 图片加载失败
      downloading: false, // 下载中状态
      resolvedUrl: '' // 通过 fileId + serviceName 解析出的 URL
    }
  },
  computed: {
    // 最终展示的图片 URL
    effectiveImageUrl() {
      return this.imageUrl || this.resolvedUrl
    },
    // 图片样式（仅处理缩放和旋转）
    imageStyle() {
      return {
        transform: `scale(${this.scale}) rotate(${this.rotate}deg)`
      }
    },
    // 图片容器样式
    wrapperStyle() {
      return {
        transform: `translate(${this.translateX}px, ${this.translateY}px)`,
        cursor: this.isDragging ? 'grabbing' : 'grab'
      }
    }
  },
  watch: {
    // 监听visible变化，重置状态并按需加载
    visible(newVal) {
      if (newVal) {
        this.resetImageTransform()
        this.loading = true
        this.loadError = false
        this.resolvedUrl = ''
        this._resolveFileId()
        this.$nextTick(() => {
          this.focusContainer()
        })
      }
    },
    // 监听图片URL变化，重新加载
    imageUrl() {
      this.loading = true
      this.loadError = false
    },
    // fileId 变化时重新解析
    fileId() {
      if (this.visible) {
        this.resolvedUrl = ''
        this._resolveFileId()
      }
    }
  },
  mounted() {
    this.appendToBodyIfNeeded()
    document.addEventListener('keydown', this.handleGlobalKeydown)
    if (this.visible) {
      this._resolveFileId()
    }
  },
  updated() {
    this.appendToBodyIfNeeded()
  },
  beforeDestroy() {
    if (this.$el && this.$el.parentNode === document.body) {
      document.body.removeChild(this.$el)
    }
    document.removeEventListener('keydown', this.handleGlobalKeydown)
    document.removeEventListener('mousemove', this.onDrag)
    document.removeEventListener('mouseup', this.endDrag)
  },
  methods: {
    // 处理全局键盘事件（使用 event.key 替代废弃的 keyCode）
    handleGlobalKeydown(event) {
      if (event.key === 'Escape' && this.visible) {
        event.preventDefault()
        event.stopPropagation()
        this.handleClose()
      }
    },

    // 处理容器内键盘事件
    handleKeydown(event) {
      if (event.key === 'Escape') {
        event.preventDefault()
        event.stopPropagation()
        this.handleClose()
      }
    },

    // 聚焦到预览容器
    focusContainer() {
      if (this.$refs.previewContainer) {
        this.$refs.previewContainer.focus()
      }
    },

    // 图片加载完成
    onImageLoad() {
      this.loading = false
      this.loadError = false
    },

    // 图片加载失败
    onImageError() {
      this.loading = false
      this.loadError = true
    },

    // 重试加载图片
    retryLoad() {
      this.loading = true
      this.loadError = false
      if (this.fileId && this.serviceName && !this.imageUrl) {
        this.resolvedUrl = ''
        this._resolveFileId()
        return
      }
      // 通过添加时间戳强制重新加载
      const img = this.$refs.previewImage
      if (img) {
        const url = this.effectiveImageUrl
        const separator = url.includes('?') ? '&' : '?'
        img.src = `${url}${separator}_t=${Date.now()}`
      }
    },

    // 通过 fileId + serviceName 解析真实图片 URL
    async _resolveFileId() {
      if (!this.fileId || !this.serviceName || this.imageUrl) return
      try {
        const svc = createFileImageService({ serviceName: this.serviceName })
        this.resolvedUrl = await svc.getImageUrl(this.fileId)
      } catch (e) {
        console.error('[ImagePreviewModal] 图片URL解析失败:', e)
        this.loading = false
        this.loadError = true
      }
    },

    // 放大（同时回归居中）
    zoomIn() {
      this.scale = Math.min(this.scale + ZOOM_CONFIG.STEP, ZOOM_CONFIG.MAX)
      this.centerImage()
    },

    // 缩小（同时回归居中）
    zoomOut() {
      this.scale = Math.max(this.scale - ZOOM_CONFIG.STEP, ZOOM_CONFIG.MIN)
      this.centerImage()
    },

    // 图片回归居中
    centerImage() {
      this.translateX = 0
      this.translateY = 0
    },

    // 向左旋转（同时回归居中）
    rotateLeft() {
      this.rotate -= ROTATE_STEP
      this.centerImage()
    },

    // 向右旋转（同时回归居中）
    rotateRight() {
      this.rotate += ROTATE_STEP
      this.centerImage()
    },

    // 重置图片变换
    resetImageTransform() {
      this.scale = 1
      this.rotate = 0
      this.translateX = 0
      this.translateY = 0
    },

    // 鼠标滚轮缩放（居中缩放，与按钮行为一致）
    handleWheel(event) {
      event.preventDefault()
      
      const delta = event.deltaY > 0 ? -ZOOM_CONFIG.STEP : ZOOM_CONFIG.STEP
      const newScale = Math.min(Math.max(ZOOM_CONFIG.MIN, this.scale + delta), ZOOM_CONFIG.MAX)
      
      // 如果缩放值没有变化，直接返回
      if (newScale === this.scale) return

      // 缩放时居中，与按钮行为保持一致
      this.scale = newScale
      this.centerImage()
    },

    // 开始拖动（鼠标按下）
    startDrag(event) {
      // 只响应左键拖动
      if (event.button !== 0) return
      // 防止选中文字等默认行为
      event.preventDefault()
      this.isDragging = true
      this.dragStartX = event.clientX - this.translateX
      this.dragStartY = event.clientY - this.translateY
      // 添加全局鼠标事件监听，确保在容器外松开也能停止拖动
      document.addEventListener('mousemove', this.onDrag)
      document.addEventListener('mouseup', this.endDrag)
    },

    // 拖动中
    onDrag(event) {
      if (!this.isDragging) return
      this.translateX = event.clientX - this.dragStartX
      this.translateY = event.clientY - this.dragStartY
    },

    // 结束拖动（鼠标松开）
    endDrag() {
      if (!this.isDragging) return
      this.isDragging = false
      // 移除全局鼠标事件监听
      document.removeEventListener('mousemove', this.onDrag)
      document.removeEventListener('mouseup', this.endDrag)
    },

    // 下载图片（支持跨域）
    async downloadImage() {
      const url = this.effectiveImageUrl
      if (!url || this.downloading) return

      this.downloading = true
      try {
        // 尝试通过 fetch 下载（支持跨域）
        const response = await fetch(url, { mode: 'cors' })
        if (!response.ok) throw new Error('下载失败')

        const blob = await response.blob()
        const blobUrl = URL.createObjectURL(blob)
        const link = document.createElement('a')
        link.href = blobUrl
        link.download = `${this.imageName}_${Date.now()}.${this.getImageExtension(url)}`
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(blobUrl)
      } catch {
        // 降级方案：直接使用 a 标签下载（可能会打开新窗口）
        const link = document.createElement('a')
        link.href = url
        link.download = `${this.imageName}_${Date.now()}.${this.getImageExtension(url)}`
        link.target = '_blank'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      } finally {
        this.downloading = false
      }
    },

    // 获取图片扩展名
    getImageExtension(url) {
      const match = url.match(/\.(jpeg|jpg|gif|png|bmp|webp)/i)
      return match ? match[1].toLowerCase() : 'png'
    },

    // 关闭模态框
    handleClose() {
      this.resetImageTransform()
      this.$emit('close')
    },

    // 统一挂载到 body，避免在 Drawer 等有 transform/overflow 的容器内出现层级和闪烁问题
    appendToBodyIfNeeded() {
      if (this.visible && this.$el && this.$el.parentNode !== document.body) {
        document.body.appendChild(this.$el)
      }
    }
  }
}
</script>

<style lang="less" scoped>
// 全屏预览容器
.fullscreen-preview-wrapper {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10000;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  flex-direction: column;
}

// 图片预览容器（占满全屏）
.image-preview-container {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  position: relative;
  cursor: grab;
  outline: none;

  &.dragging {
    cursor: grabbing;
  }
}

.image-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  transition: transform 0.1s ease;
  will-change: transform;
}

.preview-image {
  display: block;
  max-width: 90vw;
  max-height: 90vh;
  width: auto;
  height: auto;
  object-fit: contain;
  transition: transform 0.3s ease;
  user-select: none;
  -webkit-user-drag: none;
}

// 加载中样式
.loading-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  color: #fff;
}

// 加载失败样式
.error-wrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  color: rgba(255, 255, 255, 0.65);

  .error-icon {
    font-size: 64px;
    margin-bottom: 16px;
    color: rgba(255, 255, 255, 0.45);
  }

  p {
    margin-bottom: 8px;
  }
}

// 底部工具栏样式
.bottom-toolbar {
  position: fixed;
  bottom: 40px;
  left: 0;
  right: 0;
  z-index: 1011;
  display: flex;
  justify-content: center;
  pointer-events: none;

  .toolbar-content {
    display: flex;
    align-items: center;
    gap: 8px;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(8px);
    border-radius: 24px;
    padding: 10px 20px;
    pointer-events: auto;
    border: 1px solid rgba(255, 255, 255, 0.15);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
  }

  .toolbar-divider {
    width: 1px;
    height: 20px;
    background: rgba(255, 255, 255, 0.2);
    margin: 0 4px;
  }

  .toolbar-btn {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.2);
    color: #fff;
    transition: all 0.3s ease;

    &:hover {
      background: rgba(255, 255, 255, 0.25);
      border-color: rgba(255, 255, 255, 0.3);
      color: #40a9ff;
      transform: translateY(-2px);
    }

    &.close-btn {
      &:hover {
        color: #ff4d4f;
      }
    }
  }
}
</style>
