<template>
  <!-- 截图展示：与 4T 相同的全屏透明层 + 可拖动/缩放面板，不阻挡地图操作 -->
  <div v-show="visible" class="screenshot-gallery-root" :class="{ 'sg-ready': layoutReady }">
    <div class="sg-panel" :style="panelStyle">
      <div class="sg-toolbar" @mousedown="onDragStart">
        <span class="sg-title">截图展示</span>
        <div class="sg-toolbar-btns" @mousedown.stop>
          <input
            ref="fileInput"
            type="file"
            accept="image/*"
            multiple
            class="sg-hidden-file"
            @change="onFilesSelected"
          />
          <button type="button" class="sg-txt-btn" @click="triggerPick">添加</button>
          <button type="button" class="sg-txt-btn" :disabled="!hasImages" @click="removeCurrent">删除</button>
          <button type="button" class="sg-icon-btn" :disabled="!canPrev" title="上一张" @click="prev">‹</button>
          <span class="sg-counter">{{ pageLabel }}</span>
          <button type="button" class="sg-icon-btn" :disabled="!canNext" title="下一张" @click="next">›</button>
          <button type="button" class="sg-close" title="关闭" @click="$emit('update:visible', false)">×</button>
        </div>
      </div>

      <div class="sg-body">
        <div v-if="!hasImages" class="sg-empty">点击「添加」插入图片；多图可使用两侧箭头翻页</div>
        <div v-else class="sg-img-frame">
          <img :key="currentIndex" :src="currentSrc" alt="" class="sg-img" draggable="false" />
        </div>
      </div>

      <div class="sg-resize" @mousedown="onResizeStart" title="拖动调整大小"></div>
    </div>
  </div>
</template>

<script>
import { saveScreenshotGalleryData, getScreenshotGalleryData } from '@/api/system/routes'

const MAX_IMAGES = 80

export default {
  name: 'ScreenshotGalleryPanel',
  props: {
    visible: { type: Boolean, default: false },
    roomId: { type: [String, Number], default: null }
  },
  data() {
    return {
      images: [],
      currentIndex: 0,
      layoutReady: false,
      isDragging: false,
      dragStartX: 0,
      dragStartY: 0,
      panelLeft: null,
      panelTop: null,
      panelWidth: 520,
      panelHeight: 400,
      isResizing: false,
      resizeStartX: 0,
      resizeStartY: 0,
      resizeStartW: 0,
      resizeStartH: 0
    }
  },
  computed: {
    panelStyle() {
      const left = this.panelLeft != null ? this.panelLeft : 24
      const top = this.panelTop != null ? this.panelTop : 100
      return {
        left: `${left}px`,
        top: `${top}px`,
        width: `${this.panelWidth}px`,
        height: `${this.panelHeight}px`
      }
    },
    hasImages() {
      return Array.isArray(this.images) && this.images.length > 0
    },
    currentSrc() {
      if (!this.hasImages) return ''
      return this.images[this.currentIndex] || ''
    },
    canPrev() {
      return this.hasImages && this.currentIndex > 0
    },
    canNext() {
      return this.hasImages && this.currentIndex < this.images.length - 1
    },
    pageLabel() {
      if (!this.hasImages) return '0 / 0'
      return `${this.currentIndex + 1} / ${this.images.length}`
    }
  },
  watch: {
    visible: {
      handler(val) {
        if (val && this.roomId) {
          this.loadData()
        }
      },
      immediate: true
    },
    roomId: {
      handler(val) {
        if (val && this.visible) {
          this.loadData()
        }
      },
      immediate: true
    }
  },
  beforeDestroy() {
    document.removeEventListener('mousemove', this.onDragMove)
    document.removeEventListener('mouseup', this.onDragEnd)
    document.removeEventListener('mousemove', this.onResizeMove)
    document.removeEventListener('mouseup', this.onResizeEnd)
  },
  methods: {
    async loadData() {
      this.layoutReady = false
      if (!this.roomId) {
        this.layoutReady = true
        return
      }
      try {
        const res = await getScreenshotGalleryData({ roomId: this.roomId })
        let d = res && res.data
        if (d) {
          if (typeof d === 'string') {
            try {
              d = JSON.parse(d)
            } catch (e) {
              this.layoutReady = true
              return
            }
          }
          const imgs = d.images
          this.images = Array.isArray(imgs) ? imgs.filter(Boolean) : []
          this.currentIndex = this.images.length > 0 ? Math.min(this.currentIndex, this.images.length - 1) : 0
          if (d.panelSize) {
            const w = Number(d.panelSize.width)
            const h = Number(d.panelSize.height)
            if (!isNaN(w) && w >= 280 && w <= 1000) this.panelWidth = w
            if (!isNaN(h) && h >= 200 && h <= window.innerHeight - 40) this.panelHeight = h
          }
          if (d.panelPosition) {
            const left = Number(d.panelPosition.left)
            const top = Number(d.panelPosition.top)
            if (!isNaN(left) && left >= 0) this.panelLeft = Math.min(left, window.innerWidth - this.panelWidth)
            if (!isNaN(top) && top >= 0) this.panelTop = Math.min(top, window.innerHeight - this.panelHeight)
          }
        }
      } catch (e) {
        console.warn('加载截图展示失败:', e)
      } finally {
        this.layoutReady = true
      }
    },

    triggerPick() {
      this.$refs.fileInput && this.$refs.fileInput.click()
    },

    readFileAsDataURL(file) {
      return new Promise((resolve) => {
        const reader = new FileReader()
        reader.onload = (ev) => resolve(ev.target.result)
        reader.onerror = () => resolve(null)
        reader.readAsDataURL(file)
      })
    },

    async onFilesSelected(e) {
      const files = e.target.files ? Array.from(e.target.files) : []
      e.target.value = ''
      const imageFiles = files.filter((f) => f.type && f.type.startsWith('image/'))
      if (imageFiles.length === 0) return

      const remain = MAX_IMAGES - this.images.length
      if (remain <= 0) {
        this.$message.warning(`最多保存 ${MAX_IMAGES} 张图片`)
        return
      }
      const take = imageFiles.slice(0, remain)
      if (take.length < imageFiles.length) {
        this.$message.warning(`已达上限，本次仅添加 ${take.length} 张`)
      }

      const urls = []
      for (const f of take) {
        const u = await this.readFileAsDataURL(f)
        if (u) urls.push(u)
      }
      if (urls.length === 0) return
      this.images = [...this.images, ...urls]
      this.currentIndex = this.images.length - 1
      if (this.roomId) this.saveData().catch(() => {})
    },

    removeCurrent() {
      if (!this.hasImages) return
      this.images.splice(this.currentIndex, 1)
      if (this.currentIndex >= this.images.length) {
        this.currentIndex = Math.max(0, this.images.length - 1)
      }
      if (this.roomId) this.saveData().catch(() => {})
    },

    prev() {
      if (this.canPrev) this.currentIndex -= 1
    },

    next() {
      if (this.canNext) this.currentIndex += 1
    },

    async saveData() {
      if (!this.roomId) {
        this.$message.warning('请先进入任务房间后再保存')
        return
      }
      try {
        const payload = {
          images: this.images,
          panelSize: { width: this.panelWidth, height: this.panelHeight }
        }
        if (this.panelLeft != null && this.panelTop != null) {
          payload.panelPosition = { left: this.panelLeft, top: this.panelTop }
        }
        await saveScreenshotGalleryData({
          roomId: this.roomId,
          data: JSON.stringify(payload)
        })
      } catch (e) {
        console.error('保存截图展示失败:', e)
        this.$message.error('保存截图展示失败，请检查网络或权限')
      }
    },

    onDragStart(e) {
      e.preventDefault()
      this.isDragging = true
      const currentLeft = this.panelLeft != null ? this.panelLeft : 24
      const currentTop = this.panelTop != null ? this.panelTop : 100
      this.dragStartX = e.clientX - currentLeft
      this.dragStartY = e.clientY - currentTop
      document.addEventListener('mousemove', this.onDragMove)
      document.addEventListener('mouseup', this.onDragEnd)
    },

    onDragMove(e) {
      if (!this.isDragging) return
      e.preventDefault()
      let left = e.clientX - this.dragStartX
      let top = e.clientY - this.dragStartY
      left = Math.max(0, Math.min(window.innerWidth - this.panelWidth, left))
      top = Math.max(0, Math.min(window.innerHeight - this.panelHeight, top))
      this.panelLeft = left
      this.panelTop = top
    },

    onDragEnd() {
      this.isDragging = false
      document.removeEventListener('mousemove', this.onDragMove)
      document.removeEventListener('mouseup', this.onDragEnd)
      if (this.roomId) this.saveData()
    },

    onResizeStart(e) {
      e.preventDefault()
      e.stopPropagation()
      this.isResizing = true
      this.resizeStartX = e.clientX
      this.resizeStartY = e.clientY
      this.resizeStartW = this.panelWidth
      this.resizeStartH = this.panelHeight
      document.addEventListener('mousemove', this.onResizeMove)
      document.addEventListener('mouseup', this.onResizeEnd)
    },

    onResizeMove(e) {
      if (!this.isResizing) return
      e.preventDefault()
      const dx = e.clientX - this.resizeStartX
      const dy = e.clientY - this.resizeStartY
      let w = Math.max(280, Math.min(1000, this.resizeStartW + dx))
      let h = Math.max(200, Math.min(window.innerHeight - 40, this.resizeStartH + dy))
      this.panelWidth = w
      this.panelHeight = h
    },

    onResizeEnd() {
      this.isResizing = false
      document.removeEventListener('mousemove', this.onResizeMove)
      document.removeEventListener('mouseup', this.onResizeEnd)
      if (this.roomId) this.saveData()
    }
  }
}
</script>

<style scoped>
.screenshot-gallery-root {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: transparent;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease-out;
}

.screenshot-gallery-root.sg-ready {
  opacity: 1;
  pointer-events: none;
}

.screenshot-gallery-root.sg-ready .sg-panel {
  pointer-events: auto;
}

.sg-panel {
  position: fixed;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(22, 93, 255, 0.15);
  border: 1px solid #e0edff;
  overflow: hidden;
  z-index: 201;
}

.sg-toolbar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 10px 8px 14px;
  background: linear-gradient(180deg, #f9fcff 0%, #eef5ff 100%);
  border-bottom: 1px solid #ddeaff;
  cursor: move;
  user-select: none;
}

.sg-title {
  font-size: 14px;
  font-weight: 600;
  color: #165dff;
}

.sg-toolbar-btns {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: default;
}

.sg-hidden-file {
  display: none;
}

.sg-txt-btn {
  background: #ebf3ff;
  color: #165dff;
  border: 1px solid #cce5ff;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: background 0.15s;
}

.sg-txt-btn:hover:not(:disabled) {
  background: #e0edff;
}

.sg-txt-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.sg-icon-btn {
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid #cce5ff;
  background: #fff;
  color: #165dff;
  border-radius: 4px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.sg-icon-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.sg-counter {
  font-size: 12px;
  color: #546e7a;
  min-width: 52px;
  text-align: center;
}

.sg-close {
  width: 28px;
  height: 28px;
  margin-left: 4px;
  border: 1px solid #cce5ff;
  background: #ebf3ff;
  color: #165dff;
  border-radius: 50%;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.sg-close:hover {
  background: #e0edff;
}

.sg-body {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  background: #f5f9ff;
}

.sg-empty {
  font-size: 13px;
  color: #78909c;
  text-align: center;
  padding: 24px 16px;
  line-height: 1.6;
}

.sg-img-frame {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}

.sg-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  vertical-align: middle;
}

.sg-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 18px;
  height: 18px;
  cursor: nwse-resize;
  user-select: none;
  z-index: 5;
  background: linear-gradient(to top left, transparent 50%, rgba(22, 93, 255, 0.25) 50%);
}

.sg-resize:hover {
  background: linear-gradient(to top left, transparent 50%, rgba(22, 93, 255, 0.45) 50%);
}
</style>
