<template>
  <el-dialog
    v-model="dialogVisible"
    title="图片预览"
    width="90%"
    :fullscreen="fullscreen"
    :show-close="true"
    :close-on-click-modal="false"
    @close="handleClose"
  >
    <div class="image-preview-container">
      <!-- 工具栏 -->
      <div class="toolbar">
        <div class="toolbar-left">
          <span class="image-info">{{ currentImage?.name || '' }}</span>
        </div>
        <div class="toolbar-center">
          <el-button-group>
            <el-button @click="handlePrevious" :disabled="currentIndex <= 0">
              <el-icon><arrow-left /></el-icon>
              上一张
            </el-button>
            <span class="page-info">
              {{ currentIndex + 1 }} / {{ images.length }}
            </span>
            <el-button @click="handleNext" :disabled="currentIndex >= images.length - 1">
              下一张
              <el-icon><arrow-right /></el-icon>
            </el-button>
          </el-button-group>
        </div>
        <div class="toolbar-right">
          <el-button-group>
            <el-button @click="handleZoomOut" :disabled="scale <= 0.2">
              <el-icon><zoom-out /></el-icon>
            </el-button>
            <el-button disabled>{{ Math.round(scale * 100) }}%</el-button>
            <el-button @click="handleZoomIn" :disabled="scale >= 3">
              <el-icon><zoom-in /></el-icon>
            </el-button>
            <el-button @click="handleRotate">
              <el-icon><refresh-right /></el-icon>
            </el-button>
            <el-button @click="handleFullscreen">
              <el-icon><full-screen /></el-icon>
            </el-button>
          </el-button-group>
        </div>
      </div>

      <!-- 图片区域 -->
      <div class="image-wrapper" @wheel.prevent="handleWheel">
        <div
          class="image-content"
          :style="imageStyle"
        >
          <el-image
            :src="currentImage?.url"
            fit="contain"
            class="preview-image"
          >
            <template #error>
              <div class="image-error">
                <el-icon><picture-filled /></el-icon>
                <span>加载失败</span>
              </div>
            </template>
          </el-image>
        </div>
      </div>

      <!-- 缩略图列表 -->
      <div v-if="showThumbnails" class="thumbnails">
        <div
          v-for="(image, index) in images"
          :key="index"
          class="thumbnail-item"
          :class="{ active: index === currentIndex }"
          @click="handleSelectImage(index)"
        >
          <el-image
            :src="image.url"
            fit="cover"
            class="thumbnail-image"
          />
        </div>
      </div>
    </div>

    <!-- 快捷键提示 -->
    <template #footer>
      <div class="footer-tips">
        <span>快捷键:</span>
        <el-tag size="small">← →</el-tag>
        <span>切换图片</span>
        <el-tag size="small">↑ ↓</el-tag>
        <span>缩放</span>
        <el-tag size="small">R</el-tag>
        <span>旋转</span>
        <el-tag size="small">Esc</el-tag>
        <span>关闭</span>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import {
  ArrowLeft,
  ArrowRight,
  ZoomIn,
  ZoomOut,
  RefreshRight,
  FullScreen,
  PictureFilled
} from '@element-plus/icons-vue'

interface ImageItem {
  url: string
  name?: string
}

interface Props {
  visible: boolean
  images: ImageItem[]
  initialIndex?: number
  showThumbnails?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  initialIndex: 0,
  showThumbnails: true
})

const emit = defineEmits<{
  'update:visible': [value: boolean]
  'change': [index: number]
}>()

// 对话框显示状态
const dialogVisible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value)
})

// 当前图片索引
const currentIndex = ref(props.initialIndex)

// 缩放比例
const scale = ref(1)

// 旋转角度
const rotation = ref(0)

// 全屏
const fullscreen = ref(false)

// 当前图片
const currentImage = computed(() => {
  return props.images[currentIndex.value]
})

// 图片样式
const imageStyle = computed(() => {
  return {
    transform: `scale(${scale.value}) rotate(${rotation.value}deg)`,
    transition: 'transform 0.3s ease'
  }
})

// 上一张
const handlePrevious = () => {
  if (currentIndex.value > 0) {
    currentIndex.value--
    emit('change', currentIndex.value)
    resetTransform()
  }
}

// 下一张
const handleNext = () => {
  if (currentIndex.value < props.images.length - 1) {
    currentIndex.value++
    emit('change', currentIndex.value)
    resetTransform()
  }
}

// 选择图片
const handleSelectImage = (index: number) => {
  currentIndex.value = index
  emit('change', currentIndex.value)
  resetTransform()
}

// 放大
const handleZoomIn = () => {
  if (scale.value < 3) {
    scale.value = Math.min(3, scale.value + 0.1)
  }
}

// 缩小
const handleZoomOut = () => {
  if (scale.value > 0.2) {
    scale.value = Math.max(0.2, scale.value - 0.1)
  }
}

// 旋转
const handleRotate = () => {
  rotation.value = (rotation.value + 90) % 360
}

// 全屏
const handleFullscreen = () => {
  fullscreen.value = !fullscreen.value
}

// 重置变换
const resetTransform = () => {
  scale.value = 1
  rotation.value = 0
}

// 鼠标滚轮缩放
const handleWheel = (event: WheelEvent) => {
  const delta = event.deltaY
  if (delta < 0) {
    handleZoomIn()
  } else {
    handleZoomOut()
  }
}

// 关闭对话框
const handleClose = () => {
  dialogVisible.value = false
  resetTransform()
}

// 键盘事件处理
const handleKeydown = (event: KeyboardEvent) => {
  if (!dialogVisible.value) return

  switch (event.key) {
    case 'ArrowLeft':
      handlePrevious()
      break
    case 'ArrowRight':
      handleNext()
      break
    case 'ArrowUp':
      handleZoomIn()
      break
    case 'ArrowDown':
      handleZoomOut()
      break
    case 'r':
    case 'R':
      handleRotate()
      break
    case 'Escape':
      handleClose()
      break
  }
}

// 监听props变化
watch(() => props.initialIndex, (newIndex) => {
  currentIndex.value = newIndex
  resetTransform()
})

watch(() => props.visible, (visible) => {
  if (visible) {
    currentIndex.value = props.initialIndex
    resetTransform()
  }
})

// 生命周期
onMounted(() => {
  document.addEventListener('keydown', handleKeydown)
})

onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown)
})
</script>

<style scoped lang="scss">
.image-preview-container {
  display: flex;
  flex-direction: column;
  height: 70vh;
  background: var(--el-fill-color-blank);

  .toolbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--el-border-color);
    background: var(--el-bg-color);

    .toolbar-left {
      .image-info {
        font-size: 14px;
        font-weight: 500;
      }
    }

    .toolbar-center {
      .page-info {
        margin: 0 12px;
        font-size: 14px;
        color: var(--el-text-color-regular);
      }
    }
  }

  .image-wrapper {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    overflow: hidden;
    position: relative;

    .image-content {
      max-width: 100%;
      max-height: 100%;

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

      .image-error {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
        color: var(--el-text-color-secondary);
        font-size: 16px;

        .el-icon {
          font-size: 48px;
          margin-bottom: 8px;
        }
      }
    }
  }

  .thumbnails {
    display: flex;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--el-border-color);
    background: var(--el-bg-color);
    overflow-x: auto;

    .thumbnail-item {
      flex-shrink: 0;
      width: 80px;
      height: 80px;
      border: 2px solid transparent;
      border-radius: 4px;
      overflow: hidden;
      cursor: pointer;
      transition: all 0.3s;

      &.active {
        border-color: var(--el-color-primary);
      }

      &:hover {
        transform: scale(1.05);
      }

      .thumbnail-image {
        width: 100%;
        height: 100%;
      }
    }
  }
}

.footer-tips {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--el-text-color-regular);
}
</style>
