<template>
  <div class="app-container ght-container">
    <div class="ght-sidebar">
      <div class="ght-sidebar-title">工程概化图</div>
      <div
        v-for="cat in categories"
        :key="cat"
        class="ght-menu-item"
        :class="{ active: activeCategory === cat }"
        @click="switchCategory(cat)"
      >{{ cat }}</div>
    </div>
    <div class="ght-main">
      <el-card shadow="never">
        <template #header>
          <div class="card-header">
            <span>{{ activeCategory || '请选择分类' }}</span>
            <div class="ght-image-selector">
              <span
                v-for="(img, i) in imageList"
                :key="img.gh_id || i"
                class="ght-image-radio"
                :class="{ selected: selectedIndex === i }"
                @click="selectImage(i)"
              >{{ img.name || '图' + (i + 1) }}</span>
              <span v-if="!imageList.length" class="ght-no-data">暂无图片</span>
            </div>
          </div>
        </template>
        <div class="ght-viewer" v-loading="loading">
          <div class="ght-viewer-controls">
            <el-button size="small" @click="zoomIn" :disabled="zoom >= 3">放大</el-button>
            <el-button size="small" @click="zoomOut" :disabled="zoom <= 0.3">缩小</el-button>
            <el-button size="small" @click="zoom = 1">还原</el-button>
            <span class="zoom-label">{{ Math.round(zoom * 100) }}%</span>
          </div>
          <div class="ght-image-wrapper" ref="wrapperRef">
            <img
              v-if="selectedImage"
              :src="selectedImage.pathfile"
              :style="{ transform: 'scale(' + zoom + ') translate(' + panX + 'px, ' + panY + 'px)' }"
              class="ght-image"
              @mousedown="startPan"
              draggable="false"
            />
            <div v-else class="ght-empty">请选择分类查看概化图</div>
          </div>
        </div>
      </el-card>
    </div>
  </div>
</template>

<script setup name="Ght">
import { getGhtList } from '@/api/slgc/ght/index'

const categories = [
  '防汛图片', '太湖流域概化', '流域分区防洪', '城市防洪工程',
  '主要行洪通告', '钱塘江流域概化', '其他流域水系', '太湖流域主要水源'
]

const activeCategory = ref('太湖流域概化')
const imageList = ref([])
const selectedIndex = ref(0)
const loading = ref(false)
const zoom = ref(1)
const panX = ref(0)
const panY = ref(0)
const wrapperRef = ref(null)
const isPanning = ref(false)
const panStart = ref({ x: 0, y: 0 })

const selectedImage = computed(() => imageList.value[selectedIndex.value] || null)

function switchCategory(cat) {
  activeCategory.value = cat
  selectedIndex.value = 0
  zoom.value = 1
  panX.value = 0
  panY.value = 0
  loadImages(cat)
}

function selectImage(i) {
  selectedIndex.value = i
  zoom.value = 1
  panX.value = 0
  panY.value = 0
}

function zoomIn() { zoom.value = Math.min(3, +(zoom.value * 1.3).toFixed(2)) }
function zoomOut() { zoom.value = Math.max(0.3, +(zoom.value / 1.3).toFixed(2)) }

function startPan(e) {
  if (zoom.value <= 1) return
  isPanning.value = true
  panStart.value = { x: e.clientX - panX.value, y: e.clientY - panY.value }
  const onMove = (ev) => {
    if (!isPanning.value) return
    panX.value = ev.clientX - panStart.value.x
    panY.value = ev.clientY - panStart.value.y
  }
  const onUp = () => { isPanning.value = false; document.removeEventListener('mousemove', onMove); document.removeEventListener('mouseup', onUp) }
  document.addEventListener('mousemove', onMove)
  document.addEventListener('mouseup', onUp)
}

function loadImages(name) {
  loading.value = true
  getGhtList({ name }).then(res => {
    const data = res.data || []
    imageList.value = Array.isArray(data) ? data : []
    loading.value = false
  }).catch(() => { loading.value = false })
}

onMounted(() => {
  loadImages(activeCategory.value)
})
</script>

<style scoped>
.ght-container { display: flex; gap: 16px; height: calc(100vh - 120px); }
.ght-sidebar { width: 180px; flex-shrink: 0; background: #fff; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); overflow-y: auto; }
.ght-sidebar-title { font-size: 16px; font-weight: 600; padding: 16px; border-bottom: 1px solid #eee; color: #409EFF; }
.ght-menu-item { padding: 12px 16px; cursor: pointer; font-size: 14px; color: #303133; border-left: 3px solid transparent; transition: all .2s; }
.ght-menu-item:hover { background: #f5f7fa; color: #409EFF; }
.ght-menu-item.active { background: #ecf5ff; color: #409EFF; border-left-color: #409EFF; font-weight: 600; }
.ght-main { flex: 1; overflow: hidden; display: flex; flex-direction: column; }
.card-header { display: flex; justify-content: space-between; align-items: center; font-weight: 600; font-size: 16px; }
.ght-image-selector { display: flex; gap: 4px; flex-wrap: wrap; }
.ght-image-radio { display: inline-block; padding: 4px 10px; font-size: 12px; border: 1px solid #dcdfe6; border-radius: 3px; cursor: pointer; color: #606266; }
.ght-image-radio:hover { border-color: #409EFF; color: #409EFF; }
.ght-image-radio.selected { background: #409EFF; color: #fff; border-color: #409EFF; }
.ght-no-data { font-size: 12px; color: #999; }
.ght-viewer { position: relative; display: flex; flex-direction: column; height: 100%; }
.ght-viewer-controls { display: flex; gap: 8px; align-items: center; padding: 8px 0; }
.zoom-label { font-size: 13px; color: #909399; margin-left: 8px; }
.ght-image-wrapper { flex: 1; overflow: hidden; display: flex; align-items: center; justify-content: center; background: #f5f7fa; border-radius: 4px; cursor: grab; position: relative; }
.ght-image-wrapper:active { cursor: grabbing; }
.ght-image { max-width: 100%; max-height: 100%; object-fit: contain; transition: transform 0.1s; user-select: none; }
.ght-empty { color: #c0c4cc; font-size: 16px; }
</style>
