<template>
  <scroll-view class="page" scroll-y>
    <view class="banner" v-if="product.image">
      <image class="banner-img" :src="product.image" mode="widthFix" />
      <view class="banner-badge" v-if="requiredPoints > 0">{{ requiredPoints }}积分</view>
    </view>
    <view class="header">
      <view class="title">{{ product.title || product.name || '-' }}</view>
      <view class="meta" v-if="requiredPoints > 0">所需积分：{{ requiredPoints }}</view>
      <view class="meta" v-if="userPoints !== null">我的积分：{{ userPoints }}</view>
    </view>
    <view class="desc" v-if="product.description">{{ product.description }}</view>
    <view class="actions">
      <view class="qty">
        <text class="label">数量</text>
        <view class="stepper">
          <text class="btn" @tap="changeQty(-1)">-</text>
          <text class="num">{{ quantity }}</text>
          <text class="btn" @tap="changeQty(1)">+</text>
        </view>
      </view>
      <button class="redeem-btn" type="primary" @tap="onRedeem" :disabled="redeeming || !canRedeem">积分兑换</button>
      <view class="hint" v-if="requiredPoints > 0">共需积分：{{ totalRequired }}</view>
    </view>
  </scroll-view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getProductDetail, getPointsBalance, redeemProductByPoints } from '@/api/appUser'

const productId = ref('')
const product = ref({})
const quantity = ref(1)
const userPoints = ref(null)
const redeeming = ref(false)

const requiredPoints = computed(() => {
  const p = product.value || {}
  const n = Number(p.price)
  return isNaN(n) ? 0 : n
})
const totalRequired = computed(() => requiredPoints.value * quantity.value)
const canRedeem = computed(() => {
  const up = Number(userPoints.value)
  const need = Number(totalRequired.value)
  return requiredPoints.value > 0 && !isNaN(up) && up >= need
})

function changeQty(delta) {
  const next = quantity.value + delta
  quantity.value = next < 1 ? 1 : next
}

async function fetchDetail(id) {
  try {
    const res = await getProductDetail(id)
    const data = res && (res.data || res.item || res.product) ? (res.data || res.item || res.product) : res
    const img = data && (data.main_image || data.image || data.img || data.pic || '')
    const title = data && (data.title || data.name || data.product_name || '')
    const price = data && (data.price ?? data.points_required ?? data.points ?? data.integral ?? null)
    const description = data && (data.description ?? data.desc ?? data.rules ?? '')
    const albumRaw = data && data.album
    const album = normalizeAlbum(albumRaw)
    const first = album[0] || img
    product.value = { image: first, album, title, price, description, ...data }
  } catch (e) {
    uni.showToast({ title: '加载失败', icon: 'none' })
  }
}

async function fetchMyPoints() {
  try {
    const uid = uni.getStorageSync('user_id')
    const b = await getPointsBalance(uid)
    const balance = b && b.balance !== undefined ? b.balance : b
    userPoints.value = Number(balance) || 0
  } catch (e) { userPoints.value = 0 }
}

async function onRedeem() {
  const token = uni.getStorageSync('token')
  const phoneBound = !!uni.getStorageSync('phone_bound')
  if (!token || !phoneBound) {
    uni.showModal({
      title: '提示',
      content: '请先登录并绑定手机号',
      confirmText: '去登录',
      success: (res) => { if (res.confirm) uni.navigateTo({ url: '/pages/login/index' }) }
    })
    return
  }
  const need = requiredPoints.value * quantity.value
  if (!requiredPoints.value || need <= 0) {
    uni.showToast({ title: '该商品未设置积分', icon: 'none' })
    return
  }
  if (userPoints.value === null) {
    await fetchMyPoints()
  }
  if (Number(userPoints.value) < Number(need)) {
    uni.showToast({ title: '积分不足', icon: 'none' })
    return
  }
  try {
    redeeming.value = true
    const uid = uni.getStorageSync('user_id')
    await redeemProductByPoints(uid, productId.value, quantity.value)
    uni.showToast({ title: '兑换成功', icon: 'success' })
    try {
      const b = await getPointsBalance(uid)
      const balance = b && b.balance !== undefined ? b.balance : b
      userPoints.value = Number(balance) || 0
    } catch (_) {}
  } catch (e) {
    uni.showToast({ title: e && (e.message || e.errMsg) || '兑换失败', icon: 'none' })
  } finally {
    redeeming.value = false
  }
}

onLoad((opts) => {
  const id = (opts && (opts.id || opts.product_id)) || ''
  productId.value = id
  if (id) fetchDetail(id)
  fetchMyPoints()
})

function normalizeAlbum(x) {
  const result = []
  try {
    if (!x) return result
    if (Array.isArray(x)) {
      return x.map(s => String(s || '').trim()).filter(Boolean)
    }
    const s = String(x || '').trim()
    if (!s) return result
    if (s.startsWith('[') && s.endsWith(']')) {
      const arr = JSON.parse(s)
      if (Array.isArray(arr)) return arr.map(u => String(u || '').trim()).filter(Boolean)
    }
    if (s.includes(',')) {
      return s.split(',').map(u => u.trim()).filter(Boolean)
    }
    return [s]
  } catch (_) {
    return result
  }
}
</script>

<style scoped>
.page { min-height: 100vh; padding-bottom: 120rpx; background: #F8F8F8 }
.banner { position: relative; padding: 0 }
.banner-img { width: 100%; display: block }
.banner-badge { position: absolute; right: 16rpx; bottom: 16rpx; background: rgba(0,0,0,0.7); color: #fff; padding: 8rpx 16rpx; border-radius: 24rpx; font-size: 24rpx }
.header { padding: 24rpx; background: #fff }
.title { font-size: 36rpx; font-weight: 700; color: #333 }
.meta { margin-top: 8rpx; font-size: 26rpx; color: #666 }
.desc { background: #fff; padding: 0 24rpx 24rpx; font-size: 26rpx; color: #444 }
.actions { margin-top: 12rpx; padding: 24rpx; background: #fff }
.qty { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16rpx }
.label { font-size: 28rpx }
.stepper { display: flex; align-items: center; }
.btn { width: 56rpx; height: 56rpx; line-height: 56rpx; text-align: center; background: #f4f4f4; border-radius: 12rpx }
.num { width: 80rpx; text-align: center; font-size: 28rpx }
.redeem-btn { margin-top: 8rpx }
.hint { margin-top: 12rpx; font-size: 24rpx; color: #999 }
</style>
