<template>
  <div class="industrial-image-list" :class="{ 'collapsed': isCollapsed }">
    <div class="header-actions" v-if="!isCollapsed">
      <slot name="header-left">
        <a-button v-if="showImportButton" type="primary" @click="handleImportImages">
          <template #icon><icon-upload /></template>
          导入图像
        </a-button>
      </slot>
      <div class="search-bar" v-if="showSearch">
        <a-input-search
          v-model="searchKeyword"
          placeholder="输入关键字搜索"
          allow-clear
          @search="handleSearch"
          @clear="handleSearchClear"
        />
      </div>
      <slot name="header-right"></slot>
      <div class="collapse-button">
        <a-button 
          type="text" 
          @click="toggleCollapse"
        >
          <template #icon>
            <icon-up />
          </template>
          收起
        </a-button>
      </div>
    </div>
    
    <div class="image-grid" v-show="!isCollapsed">
      <div v-if="imageList.length === 0" class="empty-data">
        <icon-image class="empty-icon" />
        <p>{{ emptyText }}</p>
      </div>
      
      <div v-else class="image-thumbnails">
        <div
          v-for="image in imageList"
          :key="image.imageId"
          class="thumbnail-item"
          :class="{ active: selectedImageId === image.imageId }"
          @click="handleImageSelect(image)"
        >
          <div class="thumbnail-image">
            <img 
              :src="getImageUrl(image.imagePath)" 
              :alt="image.imageName" 
              @error="handleImageError"
              @load="handleImageLoad"
            />
            <div class="image-placeholder" v-if="!image.imagePath">
              <icon-image />
              <span>暂无图像</span>
            </div>
            <div class="thumbnail-overlay">
              <div class="image-info">
                <p class="image-name">{{ image.imageName }}</p>
                <p class="image-size">{{ formatFileSize(image.size || 0) }}</p>
              </div>
              <div class="image-actions">
                <a-button v-if="showPreviewAction" type="text" size="small" @click.stop="handleImagePreview(image)">
                  <icon-eye />
                </a-button>
                <a-button v-if="showProcessAction" type="text" size="small" @click.stop="handleImageProcess(image)">
                  <icon-settings />
                </a-button>
                <a-button v-if="showDeleteAction" type="text" size="small" status="danger" @click.stop="handleImageDelete(image)">
                  <icon-delete />
                </a-button>
                <slot name="item-actions" :image="image"></slot>
              </div>
            </div>
          </div>
          <div class="thumbnail-info">
            <p class="thumbnail-name">{{ image.imageName }}</p>
            <div class="thumbnail-meta">
              <span class="image-type">{{ image.imageType?.toUpperCase() || 'IMAGE' }}</span>
              <span v-if="image.defectCount" class="defect-count">缺陷: {{ image.defectCount }}</span>
              <slot name="item-meta" :image="image"></slot>
            </div>
            <div class="thumbnail-extra" v-if="image.partName || image.shootingTime">
              <span v-if="image.partName" class="part-name">{{ image.partName }}</span>
              <span v-if="image.shootingTime" class="capture-time">{{ formatTime(image.shootingTime) }}</span>
            </div>
            <slot name="item-extra" :image="image"></slot>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 收起状态下的展开按钮 -->
    <div v-if="isCollapsed" class="expand-button-container">
      <a-button 
        type="primary"
        @click="toggleCollapse"
      >
        <template #icon>
          <icon-down />
        </template>
        展开图像列表
      </a-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { 
  IconUpload,
  IconImage,
  IconEye,
  IconSettings,
  IconDelete,
  IconUp,
  IconDown
} from '@arco-design/web-vue/es/icon'

export interface IndustrialImage {
  imageId: string
  imageName: string
  imagePath?: string
  imageType?: string
  size?: number
  defectCount?: number
  partName?: string
  shootingTime?: string
  [key: string]: any // 允许其他属性
}

const props = defineProps({
  imageList: {
    type: Array as () => IndustrialImage[],
    default: () => []
  },
  selectedImageId: {
    type: String,
    default: ''
  },
  baseUrl: {
    type: String,
    default: 'http://pms.dtyx.net:9158'
  },
  emptyText: {
    type: String,
    default: '暂无图像数据'
  },
  showImportButton: {
    type: Boolean,
    default: true
  },
  showSearch: {
    type: Boolean,
    default: true
  },
  showPreviewAction: {
    type: Boolean,
    default: true
  },
  showProcessAction: {
    type: Boolean,
    default: true
  },
  showDeleteAction: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits<{
  importImages: []
  imageSelect: [image: IndustrialImage]
  imagePreview: [image: IndustrialImage]
  imageProcess: [image: IndustrialImage]
  imageDelete: [image: IndustrialImage]
  search: [keyword: string]
  collapsedChange: [collapsed: boolean]
}>()

const searchKeyword = ref('')
const isCollapsed = ref(false)

const handleImportImages = () => {
  emit('importImages')
}

const handleImageSelect = (image: IndustrialImage) => {
  emit('imageSelect', image)
}

const handleImagePreview = (image: IndustrialImage) => {
  emit('imagePreview', image)
}

const handleImageProcess = (image: IndustrialImage) => {
  emit('imageProcess', image)
}

const handleImageDelete = (image: IndustrialImage) => {
  emit('imageDelete', image)
}

const handleSearch = () => {
  emit('search', searchKeyword.value)
}

const handleSearchClear = () => {
  searchKeyword.value = ''
  emit('search', '')
}

const toggleCollapse = () => {
  isCollapsed.value = !isCollapsed.value
  emit('collapsedChange', isCollapsed.value)
}

// 图片加载处理
const handleImageLoad = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = 'block'
}

const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = 'none'
  console.warn('图片加载失败:', img.src)
}

// 获取完整的图片URL
const getImageUrl = (imagePath?: string): string => {
  if (!imagePath) return ''
  if (imagePath.startsWith('http')) return imagePath
  return `${props.baseUrl}${imagePath}`
}

// 格式化文件大小
const formatFileSize = (size: number): string => {
  if (size < 1024) return `${size} B`
  if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`
  if (size < 1024 * 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(1)} MB`
  return `${(size / (1024 * 1024 * 1024)).toFixed(1)} GB`
}

// 格式化时间
const formatTime = (timeString: string): string => {
  if (!timeString) return ''
  try {
    const date = new Date(timeString)
    return date.toLocaleDateString('zh-CN', {
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit'
    })
  } catch {
    return timeString
  }
}
</script>

<style scoped lang="scss">
.industrial-image-list {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  height: 100%;
  overflow: hidden;
  transition: height 0.3s ease;
  position: relative;

  &.collapsed {
    flex: 0 0 auto;
    height: auto;
    min-height: 0;
    max-height: 0;
    overflow: visible;
  }

  .header-actions {
    display: flex;
    gap: 12px;
    align-items: center;
    padding: 10px 16px;
    justify-content: space-between;
    background-color: #ffffff;
    border-bottom: 1px solid #f0f0f0;
    transition: all 0.3s ease;

    .search-bar {
      width: 300px;
    }

    .collapse-button {
      margin-left: auto;
    }
  }
  
  /* 收起状态下的展开按钮容器 */
  .expand-button-container {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 100;
  }

  .image-grid {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
    height: calc(100% - 60px); /* 减去header-actions的高度 */
    
    // 美化滚动条
    &::-webkit-scrollbar {
      width: 8px;
    }
    
    &::-webkit-scrollbar-track {
      background: #f1f5f9;
      border-radius: 4px;
    }
    
    &::-webkit-scrollbar-thumb {
      background: #cbd5e1;
      border-radius: 4px;
      
      &:hover {
        background: #94a3b8;
      }
    }

    .empty-data {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 200px;
      color: #6b7280;

      .empty-icon {
        font-size: 48px;
        margin-bottom: 16px;
      }

      p {
        margin: 0;
        font-size: 14px;
      }
    }

    .image-thumbnails {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 16px;

      .thumbnail-item {
        cursor: pointer;
        border: 2px solid transparent;
        border-radius: 8px;
        transition: all 0.3s ease;

        &:hover {
          border-color: #3b82f6;
          transform: translateY(-2px);
          box-shadow: 0 8px 25px -8px rgba(0, 0, 0, 0.1);
        }

        &.active {
          border-color: #3b82f6;
          background: #f0f9ff;
        }

        .thumbnail-image {
          position: relative;
          aspect-ratio: 4/3;
          overflow: hidden;
          border-radius: 6px;
          background: #f8f9fa;

          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: opacity 0.3s ease;
          }

          .image-placeholder {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background: #f8f9fa;
            color: #6b7280;
            font-size: 12px;

            .arco-icon {
              font-size: 24px;
              margin-bottom: 8px;
            }
          }

          .thumbnail-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.7) 100%);
            opacity: 0;
            transition: opacity 0.3s ease;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            padding: 12px;
            color: white;

            .image-info {
              .image-name {
                margin: 0 0 4px 0;
                font-size: 14px;
                font-weight: 500;
                text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
              }

              .image-size {
                margin: 0;
                font-size: 12px;
                opacity: 0.9;
              }
            }

            .image-actions {
              display: flex;
              gap: 8px;
              justify-content: flex-end;

              .arco-btn {
                background: rgba(255, 255, 255, 0.2);
                border: none;
                color: white;
                backdrop-filter: blur(4px);

                &:hover {
                  background: rgba(255, 255, 255, 0.3);
                  color: white;
                }

                &.arco-btn-status-danger:hover {
                  background: rgba(239, 68, 68, 0.8);
                }
              }
            }
          }

          &:hover .thumbnail-overlay {
            opacity: 1;
          }
        }

        .thumbnail-info {
          padding: 8px;

          .thumbnail-name {
            margin: 0 0 4px 0;
            font-size: 14px;
            font-weight: 500;
            color: #1f2937;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }

          .thumbnail-meta {
            display: flex;
            gap: 8px;
            align-items: center;

            .image-type {
              font-size: 12px;
              color: #6b7280;
              background: #f3f4f6;
              padding: 2px 6px;
              border-radius: 4px;
            }

            .defect-count {
              font-size: 12px;
              color: #dc2626;
              background: #fee2e2;
              padding: 2px 6px;
              border-radius: 4px;
            }
          }

          .thumbnail-extra {
            margin-top: 4px;
            display: flex;
            flex-direction: column;
            gap: 2px;

            .part-name {
              font-size: 11px;
              color: #059669;
              background: #ecfdf5;
              padding: 1px 4px;
              border-radius: 3px;
              align-self: flex-start;
            }

            .capture-time {
              font-size: 10px;
              color: #6b7280;
              opacity: 0.8;
            }
          }
        }
      }
    }
  }
}
</style> 