<template>
  <div class="commodity-card" :class="{ active: active }">
    <div class="commodity-card-image">
      <div class="before"></div>
      <div class="image">
        <img :src="mainImageSrc" />
      </div>
      <!-- 左上角 -->
      <div class="img_top_left">
        <span v-if="showSelectIcon" class="select-icon"></span>
        <slot name="top_left"></slot>
      </div>
      <!-- 右上角 -->
      <div class="img_top_right">
        <slot name="top_right"></slot>
      </div>
      <!-- 左下角 -->
      <div class="img_bottom_left">
        <slot name="bottom_left"></slot>
      </div>
      <!-- 右下角 -->
      <div class="img_bottom_right">
        <slot name="operations"></slot>
      </div>
    </div>
    <div class="commodity-card-info">
      <!-- 颜色图片列表 -->
      <div
        v-if="showImageList && hasImageList"
        class="color-image flex flex-gap-10"
      >
        <div
          v-for="(img, index) in imageList"
          :key="index"
          class="color-image-item"
        >
          <img :src="getItemImagePath(img)" />
        </div>
      </div>

      <!-- 时间信息插槽 -->
      <slot name="time"></slot>

      <!-- 名称和价格 -->
      <div
        v-if="showProductInfo && cardItem?.productName"
        class="commodity-card-name-price flex flex-justify-space-between"
      >
        <slot name="productName">
          <span>{{ cardItem?.productName }}</span>
        </slot>
        <slot name="price"></slot>
      </div>

      <!-- SKU信息 -->
      <div
        v-if="showSku && cardItem?.sku"
        class="commodity-card-sku"
        @click.stop="copy(String(cardItem?.sku))"
      >
        <img src="../assets/images/id.png" height="20" />
        <span>{{ cardItem?.sku }}</span>
      </div>
      <slot name="images"></slot>
      <!-- 自定义信息 -->
      <slot name="info"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, defineProps, withDefaults } from 'vue'
import { ElMessage } from 'element-plus'
import { PodProductList, CardOrderData } from '@/types/api/podOrder'
import type { TypesettingListData } from '../types/api/typesetting'

// 定义通用字段接口，用于处理动态属性
interface CommonFields {
  [key: string]: unknown
  variantImage?: string
  mainImage?: string
  sku?: string
  productName?: string
}

// 定义图片列表项接口
interface ImageListItem {
  [key: string]: unknown
  imagePath?: string
}

// 创建一个工具类型，用于使用字符串索引访问对象属性
type IndexableObject = Record<string, unknown>

// 扩展现有类型以确保它们有通用字段
type CardItem =
  | PodProductList
  | CardOrderData
  | TypesettingListData
  | CommonFields

// 定义 props 类型
interface Props {
  cardItem: CardItem
  active?: boolean
  showSelectIcon?: boolean
  showSku?: boolean
  showProductInfo?: boolean
  showImageList?: boolean
  imageField?: string
  imageListField?: string
  imagePathField?: string
}

// 定义默认值
const props = withDefaults(defineProps<Props>(), {
  active: false,
  showSelectIcon: true,
  showSku: false,
  showProductInfo: false,
  showImageList: false,
  imageField: 'variantImage',
  imageListField: 'imageList',
  imagePathField: 'imagePath',
})

// 获取主图片源
const mainImageSrc = computed<string>(() => {
  const item = props.cardItem as IndexableObject

  // 使用索引访问避免联合类型的属性访问问题
  if (
    props.imageField === 'variantImage' &&
    typeof item[props.imageField] === 'string'
  ) {
    return item[props.imageField] as string
  }
  if (
    props.imageField === 'mainImage' &&
    typeof item[props.imageField] === 'string'
  ) {
    return item[props.imageField] as string
  }
  // 默认返回空字符串
  return ''
})

// 获取图片列表
const imageList = computed<ImageListItem[]>(() => {
  const item = props.cardItem as IndexableObject
  const list = item[props.imageListField]
  return Array.isArray(list) ? (list as ImageListItem[]) : []
})

// 判断是否有图片列表
const hasImageList = computed<boolean>(() => {
  return imageList.value.length > 0
})

// 获取图片列表项的图片路径
function getItemImagePath(item: IndexableObject): string {
  return (item[props.imagePathField] as string) || ''
}

const copy = (text: string) => {
  navigator.clipboard.writeText(text)
  ElMessage.success('复制成功')
}
</script>

<style lang="scss" scoped>
.commodity-card {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.commodity-card-image {
  position: relative;
  border: 1px solid #eee;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  .img_top_left {
    position: absolute;
    top: 5px;
    left: 5px;
    display: flex;
    align-items: center;
    gap: 4px;
  }

  .img_top_right {
    position: absolute;
    top: 5px;
    right: 5px;
  }

  .img_bottom_left {
    position: absolute;
    bottom: 5px;
    left: 5px;
  }

  .img_bottom_right {
    position: absolute;
    bottom: 5px;
    right: 5px;
    display: flex;
    align-items: center;
    :deep(.svg-icon) {
      width: 2em;
      height: 2em;
    }
  }
}

.before {
  height: 0;
  padding-top: 120%;
}

.image {
  position: absolute;
  inset: 0;
  img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
  }
}

.color-image {
  .color-image-item {
    width: 50px;
    height: 50px;
  }
  img {
    width: 100%;
    height: 100%;
  }
}

.commodity-card-info {
  flex: 1;
  padding: 10px;
  font-size: 14px;
  background: linear-gradient(
    90deg,
    rgba(228, 228, 228, 0.4) 0%,
    rgba(255, 255, 255, 1) 100%
  );
}

.commodity-card-name-price {
  height: 30px;
  line-height: 30px;
}

.commodity-card-sku {
  display: flex;
  align-items: center;
  gap: 5px;
  background-color: #fff;
  cursor: pointer;
}

.select-icon {
  position: relative;
  display: block;
  width: 16px;
  height: 16px;
  border: 1px solid #cccccc;
  box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.4) inset;
  border-radius: 8px;
  background: #fff;
}

.commodity-card.active .select-icon {
  background: #4168ff;
  position: relative;
  border-color: #4168ff;
  box-shadow: none;
  font-size: 18px;
  top: -1px;
  left: -1px;
}

.commodity-card.active .select-icon::after {
  position: absolute;
  content: '';
  top: 0px;
  left: 4px;
  width: 4px;
  height: 8px;
  border-width: 2px;
  border-style: solid;
  border-color: transparent #fff #fff transparent;
  transform: rotate(45deg) scale(0.8);
}
</style>
