<template>
  <!-- 产品详情页 - 接入 /public/goods/{goodId} 接口 -->
  <view class="detail-page" :style="{ paddingTop: statusBarHeight + 'px' }">
    <!-- 产品图片轮播 + 指示点 -->
    <DetailSwiper :images="productImages" />

    <!-- 产品信息：名称/SKU/国家/价格/4列快捷信息 -->
    <ProductInfo :info="product" />

    <!-- 灰色分隔条 -->
    <view class="section-divider" v-if="colors.length"></view>

    <!-- 颜色选择：根据 variants 传 enabled 可用态 -->
    <ColorSelector
      v-if="colors.length"
      :list="colorListWithAvailability"
      :selected-id="selectedColorId"
      @select="selectColor"
    />

    <!-- 灰色分隔条 -->
    <view class="section-divider" v-if="sizes.length"></view>

    <!-- 尺码选择：根据 variants 传 enabled 可用态 -->
    <SizeSelector
      v-if="sizes.length"
      :list="sizeListWithAvailability"
      :selected="selectedSize"
      @select="selectSize"
    />

    <!-- 灰色分隔条 -->
    <view class="section-divider" v-if="productParams.length"></view>

    <!-- 产品参数（含可展开的补充说明） -->
    <ParamsTable v-if="productParams.length" :list="productParams" />

    <!-- 灰色分隔条 -->
    <view class="section-divider" v-if="sizeChart.rows && sizeChart.rows.length"></view>

    <!-- 产品尺码表 -->
    <SizeChart v-if="sizeChart.rows && sizeChart.rows.length" :data="sizeChart" />

    <!-- 灰色分隔条 -->
    <view class="section-divider" v-if="packaging"></view>

    <!-- 包装规格表（接口暂未提供，预留） -->
    <PackagingSpec v-if="packaging" :data="packaging" />
  </view>
</template>

<script>
import DetailSwiper from './components/DetailSwiper.vue'
import ProductInfo from './components/ProductInfo.vue'
import ColorSelector from './components/ColorSelector.vue'
import SizeSelector from './components/SizeSelector.vue'
import ParamsTable from './components/ParamsTable.vue'
import SizeChart from './components/SizeChart.vue'
import PackagingSpec from './components/PackagingSpec.vue'

import { getGoodsDetail } from '@/api/public.js'

export default {
  components: {
    DetailSwiper,
    ProductInfo,
    ColorSelector,
    SizeSelector,
    ParamsTable,
    SizeChart,
    PackagingSpec
  },
  data() {
    return {
      statusBarHeight: 20,
      productId: null,
      loading: false,
      product: {
        name: '',
        sku: '',
        country: '',
        price: { symbol: '￥', integer: '0', decimal: '' },
        quickInfo: []
      },
      productImages: [],
      colors: [],
      selectedColorId: '',
      sizes: [],
      selectedSize: '',
      productParams: [],
      sizeChart: {},
      // 变体列表（来自接口 variants），用于校验尺码+颜色组合、获取价格、包装规格
      variants: [],
      // 按颜色分组的图片映射：{ [colorId]: [url, ...] }（来自 detail.mediaByColor）
      mediaByColor: {},
      // 默认轮播图（无颜色或 mediaByColor 缺失时使用，来自 detail.media.images）
      defaultImages: [],
      packaging: null
    }
  },
  onLoad(options) {
    try {
      const sysInfo = uni.getSystemInfoSync()
      this.statusBarHeight = sysInfo.statusBarHeight || 20
    } catch (e) {
      this.statusBarHeight = 20
    }
    if (options && options.id) {
      this.productId = options.id
      this.loadDetail(options.id)
    }
  },
  methods: {
    async loadDetail(goodId) {
      if (!goodId) return
      this.loading = true
      try {
        const res = await getGoodsDetail(goodId)
        const detail = (res && res.data && res.data.data) || {}
        this.applyDetail(detail)
      } catch (err) {
        console.error('[product-detail loadDetail Error]', err)
      } finally {
        this.loading = false
      }
    },

    /**
     * 将接口详情数据映射为各组件所需结构
     */
    applyDetail(detail) {
      // 1. 产品信息：名称 / SKU / 国家 / 价格 / 4 列快捷信息
      this.product = {
        name: detail.goodName || '—',
        sku: detail.productCode || '—',
        country: (detail.country && detail.country.countryName) || '—',
        price: this.parsePrice(detail.price),
        quickInfo: [
          { label: '生产工艺', value: (detail.details && detail.details.productionProcess) || '—' },
          {
            label: '发货时效',
            value: detail.productionCycleHours ? detail.productionCycleHours + '小时' : '—'
          },
          { label: '印花', value: (detail.details && detail.details.designArea) || '—' },
          { label: '产品编码', value: detail.productCode || '—' }
        ]
      }

      // 2. 图片画廊：
      //  - defaultImages：来自 detail.media.images（按 sortOrder 升序，首图置顶）
      //  - mediaByColor：来自 detail.mediaByColor，结构 [{ colorId, colorName, colorHex, images:[url,...] }]
      //  顶部轮播优先显示选中颜色对应的图片；mediaByColor 缺失或当前颜色无图时回退到 defaultImages
      const media = detail.media || {}
      let defaultImages = (media.images || [])
        .slice()
        .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
        .map((img) => img.url)
        .filter((url) => url)
      if (media.primaryImageUrl && defaultImages.indexOf(media.primaryImageUrl) === -1) {
        defaultImages.unshift(media.primaryImageUrl)
      }
      if (!defaultImages.length && detail.image) {
        defaultImages.push(detail.image)
      }
      this.defaultImages = defaultImages
      this.mediaByColor = this.buildMediaByColor(detail.mediaByColor)

      // 3. 颜色：仅取启用项，按 sortOrder 升序
      const colors = ((detail.options && detail.options.colors) || [])
        .filter((c) => c.enabled !== false)
        .slice()
        .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
        .map((c) => ({ id: c.id, name: c.name, value: c.hex }))
      this.colors = colors
      this.selectedColorId = colors.length ? colors[0].id : ''

      // 4. 尺码：仅取启用项，按 sortOrder 升序
      const sizes = ((detail.options && detail.options.sizes) || [])
        .filter((s) => s.enabled !== false)
        .slice()
        .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
        .map((s) => s.name)
      this.sizes = sizes
      this.selectedSize = sizes.length ? sizes[0] : ''

      // 5. 产品参数（含可展开的"补充说明"）
      this.productParams = this.buildParams(detail)

      // 6. 变体：用于尺码+颜色校验、价格联动、包装规格来源
      this.variants = Array.isArray(detail.variants) ? detail.variants.slice() : []

      // 7. 尺码表
      this.sizeChart = this.buildSizeChart(detail.sizeChart)

      // 8. 包装规格（从 variants 按尺码去重生成）
      this.packaging = this.buildPackaging(this.variants)

      // 9. 初始价格（按默认选中的 尺码+颜色 匹配变体价格）
      this.syncPriceByVariant()

      // 10. 初始轮播图（按默认选中颜色取 mediaByColor，无则回退 defaultImages）
      this.syncImagesByColor()
    },

    /**
     * 将接口 mediaByColor 数组转为 colorId -> [url] 映射
     * 入参：[{ colorId, colorName, colorHex, images:[url,...] }]
     * 出参：{ '1126198': [url, ...], ... }
     */
    buildMediaByColor(list) {
      const map = {}
      if (Array.isArray(list)) {
        list.forEach((item) => {
          if (!item || item.colorId == null) return
          const imgs = Array.isArray(item.images) ? item.images.filter((u) => u) : []
          if (imgs.length) map[String(item.colorId)] = imgs
        })
      }
      return map
    },

    /**
     * 按当前 selectedColorId 同步顶部轮播图：
     * - 若 mediaByColor 命中且该颜色有图，则使用该颜色的图片数组
     * - 否则回退到 defaultImages
     */
    syncImagesByColor() {
      const colorId = this.selectedColorId
      const byColor = this.mediaByColor || {}
      const imgs = colorId && byColor[String(colorId)] ? byColor[String(colorId)] : this.defaultImages
      this.productImages = (imgs || []).slice()
    },

    /**
     * 价格拆分：'35' → { symbol:'￥', integer:'35', decimal:'' }
     *              '35.50' → { symbol:'￥', integer:'35', decimal:'.50' }
     */
    parsePrice(price) {
      const raw = price != null ? String(price) : ''
      let integer = raw
      let decimal = ''
      const dot = raw.indexOf('.')
      if (dot >= 0) {
        integer = raw.slice(0, dot) || '0'
        decimal = raw.slice(dot)
      }
      return { symbol: '￥', integer: integer || '0', decimal: decimal }
    },

    /**
     * 构造产品参数列表：克重 / 材质 / 补充说明（可展开）
     */
    buildParams(detail) {
      const d = detail.details || {}
      const params = []
      if (detail.minWeightG) {
        params.push({ label: '克重', value: detail.minWeightG + 'g' })
      }
      if (d.materialDescription) {
        params.push({ label: '材质', value: d.materialDescription })
      }
      const expandableText = this.buildExpandableText(d)
      if (expandableText) {
        params.push({ label: '补充说明', expandable: true, value: expandableText })
      }
      return params
    },

    /**
     * 拼接"补充说明"多段文本：材质说明/产品性能/适用情景/洗涤说明/图片要求/特殊说明/温馨提示
     */
    buildExpandableText(d) {
      const lines = []
      if (d.materialDescription) lines.push('【 材质说明 】\n' + d.materialDescription)
      if (d.productPerformance) lines.push('【 产品性能 】\n' + d.productPerformance)
      if (d.applicableScenarios) lines.push('【 适用情景 】\n' + d.applicableScenarios)
      if (d.washingInstructions) lines.push('【 洗涤说明 】\n' + d.washingInstructions)
      if (d.pictureRequest) lines.push('【 图片要求 】\n' + d.pictureRequest)
      if (d.specialDescription) lines.push('【 特殊说明 】\n' + d.specialDescription)
      if (d.reminder) lines.push('【 温馨提醒 】\n' + d.reminder)
      return lines.join('\n')
    },

    /**
     * 构造尺码表：接口 measurements.key (chest/bodyLength/shoulder/sleeveLength) → 表格列
     */
    buildSizeChart(sizeChart) {
      if (!sizeChart || !sizeChart.rows || !sizeChart.rows.length) return {}
      const columns = ['尺码', '肩宽', '胸围', '衣长', '袖长']
      const rows = sizeChart.rows.map((row) => {
        const measurements = row.measurements || []
        const get = (key) => {
          const m = measurements.find((x) => x.key === key)
          return m ? m.cm : ''
        }
        return {
          size: row.sizeName || '',
          shoulder: get('shoulder'),
          chest: get('chest'),
          length: get('bodyLength'),
          sleeve: get('sleeveLength')
        }
      })
      return { unit: 'cm', columns, rows }
    },

    /**
     * 构建包装规格表（按尺码聚合 → 每行一个尺码）
     * 数据来源：variants[].{ sizeId, sizeName, boxLengthCm, boxWidthCm, boxHeightCm, weightG }
     */
    buildPackaging(variants) {
      if (!Array.isArray(variants) || !variants.length) return null
      const CM_TO_IN = 0.393701
      const G_TO_LB = 0.00220462
      const map = new Map()
      variants.forEach((v) => {
        if (!v || !v.sizeId) return
        if (map.has(v.sizeId)) return // 按尺码取第一条（所有颜色的包装尺寸/重量一般相同）
        const l = parseFloat(v.boxLengthCm) || 0
        const w = parseFloat(v.boxWidthCm) || 0
        const h = parseFloat(v.boxHeightCm) || 0
        const g = parseFloat(v.weightG) || 0
        const cm3 = l * w * h
        const in3 = cm3 * Math.pow(CM_TO_IN, 3)
        map.set(v.sizeId, {
          size: v.sizeName || '',
          sizeId: v.sizeId,
          dimension: {
            cm: `${l.toFixed(1)}*${w.toFixed(1)}*${h.toFixed(1)}cm`,
            in: `${(l * CM_TO_IN).toFixed(2)}*${(w * CM_TO_IN).toFixed(2)}*${(h * CM_TO_IN).toFixed(2)}in`
          },
          volume: {
            cm: `${cm3.toFixed(2)}cm³`,
            in: `${in3.toFixed(2)}in³`
          },
          weight: {
            cm: `${g.toFixed(2)}g`,
            in: `${(g * G_TO_LB).toFixed(2)}lb`
          }
        })
      })
      if (!map.size) return null
      // 按 sizes 顺序排序（保持 S→M→L→XL 顺序）
      const orderMap = {}
      this.sizes.forEach((s, i) => (orderMap[s] = i))
      const rows = Array.from(map.values()).sort((a, b) => {
        const ai = orderMap[a.size] == null ? 999 : orderMap[a.size]
        const bi = orderMap[b.size] == null ? 999 : orderMap[b.size]
        return ai - bi
      })
      return {
        unit: 'cm',
        columns: ['尺码', '尺寸', '体积', '重量'],
        rows
      }
    },

    /**
     * 根据当前 selectedColorId + selectedSize 找到匹配的 variant
     * 命中后更新 ProductInfo 的价格；找不到则保持原商品价格
     */
    findVariant() {
      const sizeName = this.selectedSize
      const colorId = this.selectedColorId
      if (!sizeName || !colorId || !this.variants.length) return null
      return (
        this.variants.find(
          (v) =>
            v &&
            String(v.colorId) === String(colorId) &&
            String(v.sizeName) === String(sizeName)
        ) || null
      )
    },
    syncPriceByVariant() {
      const v = this.findVariant()
      if (v && v.price != null) {
        this.$set(this.product, 'price', this.parsePrice(v.price))
      }
    },

    /**
     * 颜色列表 + 根据已选尺码标记该颜色是否可用（有对应启用的 variant）
     * 数据项: { id, name, value, enabled }
     */
    selectColor(id) {
      this.selectedColorId = id
      this.syncImagesByColor()
      this.syncPriceByVariant()
    },
    /**
     * 尺码列表 + 根据已选颜色标记该尺码是否可用
     * 数据项: 直接返回字符串（SizeSelector 兼容），不可用的对应按钮会 disabled 掉，因此用对象包一层
     */
    selectSize(size) {
      this.selectedSize = size
      this.syncPriceByVariant()
    }
  },
  computed: {
    /**
     * 颜色列表 + 可用态标记（给 ColorSelector 用，用于 disabled 样式）
     * - 如果没选尺码：所有已 enabled 的颜色都可选
     * - 如果已选尺码：仅保留存在 (colorId + sizeName) 组合且 variant.enabled 的颜色
     */
    colorListWithAvailability() {
      const sizeName = this.selectedSize
      return this.colors.map((c) => {
        let enabled = c.enabled !== false
        if (sizeName && this.variants.length) {
          enabled = this.variants.some(
            (v) =>
              v &&
              v.enabled !== false &&
              String(v.colorId) === String(c.id) &&
              String(v.sizeName) === String(sizeName)
          )
        }
        return Object.assign({}, c, { enabled })
      })
    },
    /**
     * 尺码列表 + 可用态标记
     * SizeSelector 原始 list 是字符串数组，这里扩展为 [{ name, enabled }]
     */
    sizeListWithAvailability() {
      const colorId = this.selectedColorId
      return this.sizes.map((s) => {
        let enabled = true
        if (colorId && this.variants.length) {
          enabled = this.variants.some(
            (v) =>
              v &&
              v.enabled !== false &&
              String(v.colorId) === String(colorId) &&
              String(v.sizeName) === String(s)
          )
        }
        return { name: s, enabled }
      })
    }
  }
}
</script>

<style>
@import './product-detail.css';
</style>
