<template>
  <div class="check-items">
    <a-card class="check-items-card" :bordered="false">
      <!-- 头部 -->
      <template slot="title">
        <div class="check-items-header">
          <div class="check-items-title">
            <a-icon type="check-square" style="color: #1890FF;" />
            <span>{{title}}</span>
          </div>
          <div class="check-items-count">
            共 {{ getTotalItemsCount() }} 项
          </div>
        </div>
      </template>

      <!-- 分类卡片网格 -->
      <div class="categories-grid">
        <div
          v-for="category in checkItems"
          :key="category.category"
          class="category-card"
        >
          <!-- 卡片头部 -->
          <div class="category-card-header">
            <div class="category-info">
              <div class="category-icon">
                <a-icon :type="getCategoryIcon(category.category)" />
              </div>
              <div class="category-details">
                <div class="category-name">{{ category.category }}</div>
                <div class="category-subtitle">检查项目</div>
              </div>
            </div>
            <span :class="getCategoryStatusClass(category)" class="category-status-badge">
              {{ getCategoryStatusText(category) }}
            </span>
          </div>

          <!-- 卡片内容 -->
          <div class="category-card-content">
            <table class="category-table">
              <thead>
              <tr>
                <th>检查项</th>
                <th>值</th>
                <th>结果</th>
                <th>照片</th>
              </tr>
              </thead>
              <tbody>
              <tr
                v-for="item in category.items"
                :key="item.name"
                :class="getItemRowClass(item.status)"
              >
                <!-- 检查项名称 -->
                <td class="item-name">{{ item.name }}</td>

                <!-- 值 -->
                <td class="item-value">
                  <template v-if="isResultPhotos(item.result)">
                    <div class="result-photo-list">
                      <button
                        v-for="(photo, pIdx) in parseResultPhotos(item.result)"
                        :key="'rp-' + pIdx"
                        class="photo-thumb-btn"
                        @click="openPreview(parseResultPhotos(item.result), pIdx)"
                      >
                        <img v-if="photo.url" :src="photo.url" :alt="photo.photo_name || '照片'" />
                        <a-icon v-else type="picture" class="thumb-error-icon" />
                      </button>
                    </div>
                  </template>
                  <template v-else>{{ item.result || '—' }}</template>
                </td>

                <!-- 结果状态 -->
                <td class="item-result">
                    <span :class="getItemStatusClass(item)" class="item-status-badge">
                      {{ getStatusText(item) }}
                    </span>
                </td>

                <!-- 照片 -->
                <td class="item-photos">
                  <div class="photo-list" v-if="item.photos && item.photos.length > 0">
                    <div class="photos-wrapper">
                      <button
                        v-for="(photo, photoIndex) in item.photos.slice(0, 3)"
                        :key="getPhotoKey(photo, photoIndex)"
                        class="photo-thumb-btn"
                        @click="openPreview(item.photos, photoIndex)"
                      >
                        <!-- 有 fileId 时通过 img 展示加载中/错误/图片 -->
                        <template v-if="photo.fileId">
                          <a-spin v-if="getThumbState(photo) === 'loading'" size="small" />
                          <a-icon v-else-if="getThumbState(photo) === 'error'" type="picture" class="thumb-error-icon" />
                          <img v-else :src="thumbUrlMap[thumbCacheKey(photo)]" :alt="photo.title || '照片'" />
                        </template>
                        <!-- 直接有 url 时展示 -->
                        <img v-else-if="photo.url" :src="photo.url" :alt="photo.title || '照片'" />
                        <a-icon v-else type="picture" class="thumb-error-icon" />
                      </button>
                      <span v-if="item.photos.length > 3" class="photo-more">
                          +{{ item.photos.length - 3 }}
                        </span>
                    </div>
                  </div>
                  <span v-else class="no-photos">—</span>
                </td>
              </tr>
              </tbody>
            </table>
          </div>
        </div>

        <!-- 空状态 -->
        <div v-if="!checkItems || checkItems.length === 0" class="check-items-empty">
          <a-icon type="check-square" style="font-size: 48px; color: #d9d9d9;" />
          <p style="color: #999; margin-top: 16px;">暂无检查项数据</p>
        </div>
      </div>
    </a-card>

    <!-- 图片全屏预览 -->
    <image-preview-modal
      v-if="previewVisible"
      :visible="previewVisible"
      :image-url="currentPreviewUrl"
      :file-id="currentPreviewUrl ? null : currentPreviewFileId"
      :service-name="currentPreviewUrl ? '' : injectedServiceName"
      :image-name="`照片${previewIndex + 1}`"
      :append-to-body="true"
      @close="previewVisible = false"
    />
  </div>
</template>

<script>
import ImagePreviewModal from '@vue2-client/base-client/components/common/ImagePreviewModal/ImagePreviewModal.vue'
import { createFileImageService } from '@vue2-client/utils/fileImageService'

export default {
  name: 'CheckItems',
  components: { ImagePreviewModal },
  inject: {
    serviceName: { default: '' }
  },
  props: {
    checkItems: {
      type: Array,
      default: () => []
    },
    title: {
      type: String,
      default: '安检检查项'
    },
  },
  data () {
    return {
      previewVisible: false,
      previewIndex: 0,
      previewPhotos: [],
      thumbUrlMap: {},
      thumbStateMap: {}
    }
  },
  computed: {
    injectedServiceName () {
      return this.serviceName || ''
    },
    currentPhoto () {
      return this.previewPhotos[this.previewIndex] || null
    },
    currentPreviewUrl () {
      if (!this.currentPhoto) return ''
      if (this.currentPhoto.url) return this.currentPhoto.url
      if (this.currentPhoto.fileId) {
        const key = this.thumbCacheKey(this.currentPhoto)
        return this.thumbUrlMap[key] || ''
      }
      return ''
    },
    currentPreviewFileId () {
      if (!this.currentPhoto) return null
      return this.currentPhoto.fileId || null
    }
  },
  watch: {
    checkItems: {
      handler () { this.preloadThumbnails() },
      immediate: true,
      deep: false
    }
  },
  methods: {
    /**
     * 预加载所有 fileId 类型的照片缩略图
     */
    preloadThumbnails () {
      if (!this.checkItems || !this.injectedServiceName) return
      this.thumbUrlMap = {}
      this.thumbStateMap = {}
      this.checkItems.forEach(category => {
        if (!category.items) return
        category.items.forEach(item => {
          if (!item.photos) return
          item.photos.forEach(photo => {
            if (photo.fileId) this.loadThumb(photo)
          })
        })
      })
    },

    /**
     * 缩略图缓存必须用字符串键。若用对象作 fileId，JS 会统一变成 "[object Object]"，导致所有缩略图共用一张图。
     * 优先使用业务侧已生成的 photo.id，其次从 fileId 上解析 id。
     */
    thumbCacheKey (photo) {
      if (!photo) return ''
      if (photo.id != null && photo.id !== '') return String(photo.id)
      const raw = photo.fileId
      if (raw == null || raw === '') return ''
      if (typeof raw !== 'object') return String(raw)
      const id = raw.id ?? raw.f_id
      if (id != null && typeof id !== 'object') return String(id)
      return JSON.stringify(raw)
    },

    async loadThumb (photo) {
      const key = this.thumbCacheKey(photo)
      if (!key || !photo.fileId) return
      if (this.thumbStateMap[key] === 'loading' || this.thumbStateMap[key] === 'done') return
      this.$set(this.thumbStateMap, key, 'loading')
      try {
        const svc = createFileImageService({ serviceName: this.injectedServiceName })
        const url = await svc.getImageUrl(photo.fileId)
        if (this.thumbStateMap[key] === 'loading') {
          this.$set(this.thumbUrlMap, key, url)
          this.$set(this.thumbStateMap, key, 'done')
        }
      } catch (e) {
        console.warn(`[CheckItems] 加载缩略图失败 key=${key}:`, e.message)
        if (this.thumbStateMap[key] === 'loading') {
          this.$set(this.thumbStateMap, key, 'error')
        }
      }
    },

    getThumbState (photo) {
      const key = this.thumbCacheKey(photo)
      return this.thumbStateMap[key] || 'loading'
    },

    getPhotoKey (photo, index) {
      return this.thumbCacheKey(photo) || photo.id || index
    },

    /**
     * 判断 result 是否为照片数组
     */
    isResultPhotos (result) {
      if (!Array.isArray(result) || result.length === 0) return false
      return result.every(item => item && (item.url || item.photo_name))
    },

    /**
     * 解析 result 中的照片数组，统一格式供照片列和预览复用
     */
    parseResultPhotos (result) {
      if (!this.isResultPhotos(result)) return []
      return result.map(p => ({
        url: p.url || '',
        photo_name: p.photo_name || '',
        title: p.photo_name || '照片'
      }))
    },

    /**
     * 打开预览
     */
    openPreview (photos, index) {
      this.previewPhotos = photos
      this.previewIndex = index
      this.previewVisible = true
    },

    /**
     * 获取总检查项数量
     */
    getTotalItemsCount () {
      return this.checkItems.reduce((total, category) => {
        return total + (category.items ? category.items.length : 0)
      }, 0)
    },

    /**
     * 获取分类图标
     */
    getCategoryIcon (categoryName) {
      const iconMap = {
        燃气表: 'dashboard',
        燃气灶: 'fire',
        燃气管道: 'branches',
        热水器: 'cloud',
        燃气阀门: 'setting',
        其他设备: 'tool'
      }
      return iconMap[categoryName] || 'folder-open'
    },

    /**
     * 获取分类整体状态
     */
    getCategoryStatus (category) {
      if (!category.items || category.items.length === 0) {
        return 'unknown'
      }

      let hasPass = false
      let hasWarning = false
      let hasFail = false

      category.items.forEach(item => {
        if (item.status === 'pass') {
          hasPass = true
        } else if (item.status === 'warning') {
          hasWarning = true
        } else if (item.status === 'fail') {
          hasFail = true
        }
      })

      if (hasFail) return 'fail'
      if (hasWarning) return 'warning'
      if (hasPass) return 'pass'
      return 'unknown'
    },

    /**
     * 获取分类状态样式类
     */
    getCategoryStatusClass (category) {
      const status = this.getCategoryStatus(category)
      const classMap = {
        pass: 'badge-pass',
        warning: 'badge-warning',
        fail: 'badge-fail',
        unknown: 'badge-unknown'
      }
      return classMap[status] || 'badge-unknown'
    },

    /**
     * 获取分类状态文本
     */
    getCategoryStatusText (category) {
      const status = this.getCategoryStatus(category)
      const textMap = {
        pass: '正常',
        warning: '警告',
        fail: '隐患',
        unknown: '未知'
      }
      return textMap[status] || '未知'
    },

    /**
     * 获取项目行样式类
     */
    getItemRowClass (status) {
      const classMap = {
        pass: '',
        warning: 'item-row-warning',
        fail: 'item-row-fail',
        unknown: ''
      }
      return classMap[status] || ''
    },

    /**
     * 获取项目状态样式类
     */
    getItemStatusClass (item) {
      const classMap = {
        pass: 'item-status-pass',
        warning: 'item-status-warning',
        fail: 'item-status-fail',
        unknown: 'item-status-unknown'
      }
      return classMap[item.status] || 'item-status-unknown'
    },

    /**
     * 获取状态图标
     */
    getStatusIcon (status) {
      const iconMap = {
        pass: 'check-circle',
        warning: 'exclamation-circle',
        fail: 'close-circle',
        unknown: 'question-circle'
      }
      return iconMap[status] || 'question-circle'
    },

    /**
     * 获取状态文本
     */
    getStatusText (item) {
      const textMap = {
        pass: '正常',
        warning: '警告',
        fail: '隐患',
        unknown: '未知'
      }
      return textMap[item.status] || '未知'
    },

  }
}
</script>

<style lang="less" scoped>
/* 主容器样式 */
.check-items {
  .check-items-card {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
  }
}

/* 头部样式 */
.check-items-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.check-items-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
}

.check-items-count {
  font-size: 14px;
  color: #6b7280;
  font-weight: 400;
}

/* 分类网格样式 */
.categories-grid {
  display: grid;
  grid-template-columns: repeat(1, 1fr);
  gap: 16px;

  @media (min-width: 768px) {
    grid-template-columns: repeat(2, 1fr);
  }

  @media (min-width: 1200px) {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 分类卡片样式 */
.category-card {
  background: white;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: all 0.3s ease;

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  }
}

/* 分类卡片头部 */
.category-card-header {
  padding: 16px 20px;
  border-bottom: 1px solid #f0f1f2;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
}

.category-info {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
}

.category-icon {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: #f0f7ff;
  display: flex;
  align-items: center;
  justify-content: center;

  .anticon {
    color: #1890ff;
    font-size: 18px;
  }
}

.category-details {
  flex: 1;
}

.category-name {
  font-size: 16px;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 2px;
}

.category-subtitle {
  font-size: 12px;
  color: #6b7280;
}

.category-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid;
  white-space: nowrap; // 禁止换行，防止打印时文字竖排显示

  &.badge-pass {
    background: #f6ffed;
    color: #389e0d;
    border-color: #b7eb8f;
  }

  &.badge-warning {
    background: #fff7e6;
    color: #d46b08;
    border-color: #ffd591;
  }

  &.badge-fail {
    background: #fff1f0;
    color: #cf1322;
    border-color: #ffa39e;
  }

  &.badge-unknown {
    background: #f5f5f5;
    color: #8c8c8c;
    border-color: #d9d9d9;
  }
}

/* 分类卡片内容 */
.category-card-content {
  flex: 1;
  overflow: auto;
}

.category-table {
  width: 100%;
  border-collapse: collapse;

  th {
    padding: 12px 12px;
    text-align: left;
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 1px solid #f0f1f2;

    &:nth-child(3),
    &:nth-child(4) {
      text-align: center;
    }
  }

  td {
    padding: 10px 12px;
    border-bottom: 1px solid #f9fafb;
    vertical-align: middle;
    font-size: 13px;
  }

  tbody tr {
    transition: background-color 0.15s ease;

    &:hover {
      background: rgba(24, 144, 255, 0.02);
    }

    &.item-row-warning {
      background: rgba(250, 140, 22, 0.02);
    }

    &.item-row-fail {
      background: rgba(245, 34, 45, 0.02);
    }
  }

  .item-name {
    font-weight: 500;
    color: #1f2937;
  }

  .item-value {
    color: #374151;

    .result-photo-list {
      display: flex;
      align-items: center;
      gap: 4px;
    }
  }

  .item-result {
    text-align: center;
  }

  .item-photos {
    text-align: center;
  }
}

/* 项目状态样式 */
.item-status-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid;
  white-space: nowrap; // 禁止换行，防止打印时文字竖排显示

  &.item-status-pass {
    background: #f6ffed;
    color: #389e0d;
    border-color: #b7eb8f;
  }

  &.item-status-warning {
    background: #fff7e6;
    color: #d46b08;
    border-color: #ffd591;
  }

  &.item-status-fail {
    background: #fff1f0;
    color: #cf1322;
    border-color: #ffa39e;
  }

  &.item-status-unknown {
    background: #f5f5f5;
    color: #8c8c8c;
    border-color: #d9d9d9;
  }
}

/* 照片列表样式 */
.photo-list {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.photos-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

.photo-thumb-btn {
  width: 32px;
  height: 24px;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #e5e7eb;
  background: #f8f9fa;
  cursor: pointer;
  transition: all 0.2s ease;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;

  &:hover {
    border-color: #1890ff;
    transform: scale(1.05);
    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);
  }

  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

.thumb-error-icon {
  color: #bfbfbf;
  font-size: 14px;
}

.photo-more {
  font-size: 11px;
  color: #8c8c8c;
  margin-left: 4px;
}

.no-photos {
  color: #bfbfbf;
  font-size: 12px;
}

/* 空状态样式 */
.check-items-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px;
  text-align: center;
  color: #8c8c8c;
}

/* 响应式适配 */
@media (max-width: 768px) {
  .categories-grid {
    grid-template-columns: repeat(1, 1fr);
  }

  .category-card-header {
    padding: 12px 16px;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .category-table {
    th, td {
      padding: 8px 10px;
      font-size: 12px;
    }

    th {
      font-size: 10px;
    }
  }

  .item-status-badge {
    padding: 2px 6px;
    font-size: 10px;
  }

  .photo-thumb-btn {
    width: 24px;
    height: 18px;
  }

  .photo-more {
    font-size: 10px;
  }
}

@media (max-width: 480px) {
  .check-items-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .check-items-title {
    font-size: 14px;
  }

  .check-items-count {
    font-size: 12px;
  }

  .category-name {
    font-size: 14px;
  }

  .category-table {
    th, td {
      padding: 6px 8px;
    }
  }
}

/* Ant Design Tag 样式覆盖 */
:deep(.ant-tag) {
  margin: 0 3px;
  border: none;
  font-weight: 500;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 10px;

  &.ant-tag-green {
    background: #e6fffa;
    color: #00695c;
  }

  &.ant-tag-orange {
    background: #fff7e6;
    color: #ad4e00;
  }

  &.ant-tag-red {
    background: #ffebee;
    color: #c62828;
  }
}
</style>
