<template>
  <view class="page">
    <view class="bg-decoration"></view>
    <!-- 顶部固定区域 -->
    <view class="header-section">
      <view class="search-box">
        <view class="search-input-wrap">
          <text class="search-icon">🔍</text>
          <input class="search-input" v-model="keyword" placeholder="搜索心仪的商品" placeholder-class="placeholder-style" confirm-type="search" @confirm="onSearchConfirm" />
        </view>
      </view>
      
      <view class="filter-row">
        <view class="price-range">
          <text class="price-label">价格区间</text>
          <input class="price-input" type="number" v-model="minPrice" placeholder="最低" placeholder-class="price-ph" />
          <text class="price-sep">-</text>
          <input class="price-input" type="number" v-model="maxPrice" placeholder="最高" placeholder-class="price-ph" />
        </view>
        <button class="filter-btn" hover-class="btn-hover" @tap="onApplyFilters">筛选</button>
      </view>
    </view>

    <!-- 占位，防止内容被头部遮挡 -->
    <view class="header-placeholder"></view>

    <view v-if="loading && !products.length" class="loading-wrap"><view class="spinner"></view></view>
    
    <view class="products-container" v-else>
      <view v-if="products.length > 0" class="products-grid">
        <view class="product-item" v-for="p in products" :key="p.id" @tap="onProductTap(p)">
          <view class="product-card">
            <view class="thumb-wrap">
              <image class="product-thumb" :src="p.image" mode="aspectFill" lazy-load="true" />
               <view class="stock-tag" v-if="p.stock !== null && p.stock < 10">仅剩{{p.stock}}件</view>
            </view>
            <view class="product-info">
              <text class="product-title">{{ p.title }}</text>
              <view class="product-bottom">
                <view class="price-row" v-if="p.points">
                  <text class="points-val">{{ p.points }}</text>
                  <text class="points-unit">积分</text>
                </view>
                <view class="price-row" v-else>
                  <text class="price-symbol">￥</text>
                  <text class="price-val">{{ p.price }}</text>
                </view>
                <view class="redeem-btn" v-if="p.points" @tap.stop="onRedeemTap(p)">兑换</view>
              </view>
            </view>
          </view>
        </view>
      </view>
      <view v-else class="empty-state">
        <image class="empty-img" src="/static/empty.png" mode="widthFix" />
        <text class="empty-text">暂无相关商品</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import { onShow } from '@dcloudio/uni-app'
import { ref, computed } from 'vue'
import { request, authRequest } from '../../utils/request.js'

const products = ref([])
const CACHE_KEY = 'products_cache_v1'
const TTL_MS = 10 * 60 * 1000
const loading = ref(false)
const keyword = ref('')
const minPrice = ref('')
const maxPrice = ref('')

function apiGet(url, data = {}) {
  const token = uni.getStorageSync('token')
  const fn = token ? authRequest : request
  return fn({ url, method: 'GET', data })
}

function cleanUrl(u) {
  const s = String(u || '').trim()
  const m = s.match(/https?:\/\/[^\s'"`]+/)
  if (m && m[0]) return m[0]
  return s.replace(/[`'\"]/g, '').trim()
}

function normalizeProducts(list) {
  if (!Array.isArray(list)) return []
  return list.map((i, idx) => ({
    id: i.id ?? i.productId ?? i._id ?? i.sku_id ?? String(idx),
    image: cleanUrl(i.main_image ?? i.imageUrl ?? i.image_url ?? i.image ?? i.img ?? i.pic ?? ''),
    title: i.title ?? i.name ?? i.product_name ?? i.sku_name ?? '',
    price: (() => { const raw = i.price_sale ?? i.price ?? i.price_min ?? i.amount ?? null; return raw == null ? null : (Number(raw) / 100) })(),
    points: i.points_required ?? i.points ?? i.integral ?? null,
    stock: i.stock ?? i.inventory ?? i.quantity ?? null,
    link: cleanUrl(i.linkUrl ?? i.link_url ?? i.link ?? i.url ?? '')
  })).filter(i => i.image || i.title)
}

function onProductTap(p) {
  const id = p && p.id
  if (id !== undefined && id !== null && id !== '') {
    uni.navigateTo({ url: `/pages/shop/detail?id=${id}` })
    return
  }
  if (p.link && /^\/.+/.test(p.link)) {
    uni.navigateTo({ url: p.link })
  }
}

async function onRedeemTap(p) {
  const token = uni.getStorageSync('token')
  if (!token) {
    uni.showModal({
      title: '提示',
      content: '请先登录',
      confirmText: '去登录',
      success: (res) => { if (res.confirm) uni.navigateTo({ url: '/pages/login/index' }) }
    })
    return
  }
  
  uni.showModal({
    title: '确认兑换',
    content: `是否消耗 ${p.points} 积分兑换 ${p.title}？`,
    success: async (res) => {
      if (res.confirm) {
        uni.showLoading({ title: '兑换中...' })
        try {
          // Get user_id from storage
          const userId = uni.getStorageSync('user_id')
          if (!userId) throw new Error('用户ID不存在')
          
          await redeemProductByPoints(userId, p.id, 1)
          uni.showToast({ title: '兑换成功', icon: 'success' })
          
          // Refresh products to update stock/points if needed
          setTimeout(() => {
             loadProducts()
          }, 1500)
        } catch (e) {
          uni.showToast({ title: e.message || '兑换失败', icon: 'none' })
        } finally {
          uni.hideLoading()
        }
      }
    }
  })
}

// Filter logic
const allProducts = ref([]) // Store all fetched products for client-side filtering

function applyFilters() {
  const k = String(keyword.value || '').trim().toLowerCase()
  const min = Number(minPrice.value)
  const max = Number(maxPrice.value)
  const hasMin = !isNaN(min) && String(minPrice.value).trim() !== ''
  const hasMax = !isNaN(max) && String(maxPrice.value).trim() !== ''
  
  const list = allProducts.value
  products.value = list.filter(p => {
    const title = String(p.title || '').toLowerCase()
    if (k && !title.includes(k)) return false
    const priceNum = typeof p.price === 'number' ? p.price : Number(p.price)
    if (hasMin) {
      if (isNaN(priceNum)) return false
      if (priceNum < min) return false
    }
    if (hasMax) {
      if (isNaN(priceNum)) return false
      if (priceNum > max) return false
    }
    return true
  })
}

function onSearchConfirm() { applyFilters() }
function onApplyFilters() { applyFilters() }

async function loadProducts() {
  try {
    const cached = uni.getStorageSync(CACHE_KEY)
    if (cached && cached.data && Date.now() - cached.ts < TTL_MS) {
       allProducts.value = cached.data
       applyFilters()
       return
    }

    const first = await apiGet('/api/app/products', { page: 1 })
    // Simple extraction
    let list = []
    let total = 0
    if (first && first.list) { list = first.list; total = first.total }
    else if (first && first.data && first.data.list) { list = first.data.list; total = first.data.total }
    
    // If not too many, fetch all for better client UX
    const pageSize = 20
    const totalPages = Math.ceil((total || 0) / pageSize)
    
    if (totalPages > 1) {
       const tasks = []
       for (let p = 2; p <= totalPages; p++) {
          tasks.push(apiGet('/api/app/products', { page: p }))
       }
       const results = await Promise.allSettled(tasks)
       results.forEach(r => {
         if (r.status === 'fulfilled') {
            const val = r.value
            const subList = (val && val.list) || (val && val.data && val.data.list) || []
            if (Array.isArray(subList)) list = list.concat(subList)
         }
       })
    }
    
    const normalized = normalizeProducts(list)
    allProducts.value = normalized
    applyFilters()
    uni.setStorageSync(CACHE_KEY, { data: normalized, ts: Date.now() })

  } catch (e) {
    console.error(e)
    products.value = []
  }
}

onShow(async () => {
  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
  }
  
  loading.value = true
  await loadProducts()
  loading.value = false
})

// 分享功能
import { onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'

onShareAppMessage(() => {
  const inviteCode = uni.getStorageSync('invite_code') || (uni.getStorageSync('user_info') || {}).invite_code || ''
  return {
    title: '柯大鸭潮玩商城 - 好物等你来兑',
    path: `/pages/index/index?invite_code=${inviteCode}`,
    imageUrl: '/static/logo.png'
  }
})

onShareTimeline(() => {
  const inviteCode = uni.getStorageSync('invite_code') || (uni.getStorageSync('user_info') || {}).invite_code || ''
  return {
    title: '柯大鸭潮玩商城 - 好物等你来兑',
    query: `invite_code=${inviteCode}`,
    imageUrl: '/static/logo.png'
  }
})

</script>

<style lang="scss" scoped>
.page {
  min-height: 100vh;
  background-color: $bg-page;
  padding-bottom: 40rpx;
  position: relative;
  overflow-x: hidden;
}

.bg-decoration {
  position: fixed;
  top: 0; left: 0; width: 100%; height: 100vh;
  pointer-events: none;
  z-index: 0;
  
  &::before {
    content: '';
    position: absolute;
    top: -100rpx; left: -100rpx;
    width: 600rpx; height: 600rpx;
    background: radial-gradient(circle, rgba($brand-primary, 0.1) 0%, transparent 70%);
    filter: blur(60rpx);
    border-radius: 50%;
    opacity: 0.6;
    animation: float 10s ease-in-out infinite;
  }
  
  &::after {
    content: '';
    position: absolute;
    bottom: 10%; right: -100rpx;
    width: 500rpx; height: 500rpx;
    background: radial-gradient(circle, rgba($brand-secondary, 0.1) 0%, transparent 70%);
    filter: blur(50rpx);
    border-radius: 50%;
    opacity: 0.5;
    animation: float 15s ease-in-out infinite reverse;
  }
}

@keyframes float {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(30rpx, 50rpx); }
}

/* 顶部 Header */
.header-section {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: $bg-glass;
  backdrop-filter: blur(20rpx);
  padding: 0 24rpx 24rpx;
  box-shadow: $shadow-sm;
  border-bottom: 1rpx solid $border-color-light;
}
.header-placeholder {
  height: 160rpx; /* 根据 header 高度调整 */
}

.page-title {
  font-size: 36rpx;
  font-weight: 800;
  color: $text-main;
  padding: 20rpx 0;
}

/* 搜索框 */
.search-box {
  margin-bottom: 20rpx;
  margin-top: 20rpx;
}
.search-input-wrap {
  display: flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: $radius-round;
  padding: 18rpx 24rpx;
  transition: all 0.3s;
}
.search-input-wrap:focus-within {
  background: $bg-card;
  border-color: $brand-primary;
  box-shadow: 0 0 0 4rpx rgba($brand-primary, 0.1);
}
.search-icon {
  font-size: 28rpx;
  margin-right: 16rpx;
  opacity: 0.5;
}
.search-input {
  flex: 1;
  font-size: 28rpx;
  color: $text-main;
}
.placeholder-style {
  color: $text-tertiary;
}

/* 筛选行 */
.filter-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20rpx;
}
.price-range {
  flex: 1;
  display: flex;
  align-items: center;
  background: $bg-secondary;
  border-radius: $radius-md;
  padding: 10rpx 20rpx;
}
.price-label {
  font-size: 24rpx;
  color: $text-sub;
  margin-right: 16rpx;
}
.price-input {
  flex: 1;
  font-size: 26rpx;
  text-align: center;
  color: $text-main;
}
.price-ph {
  color: $text-tertiary;
  font-size: 24rpx;
}
.price-sep {
  color: $text-tertiary;
  margin: 0 10rpx;
}
.filter-btn {
  background: $gradient-brand;
  color: $text-inverse;
  font-size: 26rpx;
  font-weight: 600;
  border-radius: $radius-md;
  padding: 0 32rpx;
  height: 64rpx;
  line-height: 64rpx;
  border: none;
  box-shadow: $shadow-sm;
}
.btn-hover {
  opacity: 0.9;
  transform: scale(0.98);
}

/* 商品 Grid 容器 */
.products-container {
  padding: 24rpx;
}
.products-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20rpx;
}

/* 商品卡片 */
.product-item {
  animation: fadeInUp 0.5s ease-out backwards;
}
@for $i from 1 through 10 {
  .product-item:nth-child(#{$i}) {
    animation-delay: #{$i * 0.05}s;
  }
}

.product-card {
  background: $bg-card;
  border-radius: $radius-lg;
  overflow: hidden;
  box-shadow: $shadow-card;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;
}
.product-item:active .product-card {
  transform: scale(0.98);
  box-shadow: $shadow-sm;
}

.thumb-wrap {
  position: relative;
  width: 100%;
  padding-top: 100%; /* 1:1 Aspect Ratio */
  background: $bg-secondary;
}
.product-thumb {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.stock-tag {
  position: absolute;
  bottom: 0;
  right: 0;
  background: rgba($accent-red, 0.9);
  color: #fff;
  font-size: 20rpx;
  padding: 4rpx 12rpx;
  border-top-left-radius: 12rpx;
  backdrop-filter: blur(4px);
  font-weight: 700;
  box-shadow: 0 -2rpx 8rpx rgba(0,0,0,0.1);
}

.product-info {
  padding: 20rpx;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.product-title {
  font-size: 28rpx;
  color: $text-main;
  line-height: 1.4;
  height: 2.8em; /* 2 lines */
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  margin-bottom: 16rpx;
  font-weight: 600;
}

.product-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8rpx;
}
.price-row {
  display: flex; align-items: baseline;
}
.points-val { font-size: 36rpx; font-weight: 700; color: #FF9800; }
.points-unit { font-size: 22rpx; color: #FF9800; margin-left: 4rpx; }
.price-symbol { font-size: 24rpx; color: #FF3B30; }
.price-val { font-size: 36rpx; font-weight: 700; color: #FF3B30; }

.redeem-btn {
  background: #FF9800;
  color: #fff;
  font-size: 24rpx;
  padding: 8rpx 20rpx;
  border-radius: 30rpx;
  margin-left: auto;
}

/* Loading & Empty */
.loading-wrap {
  padding: 100rpx 0;
  display: flex;
  justify-content: center;
}
.spinner {
  width: 50rpx;
  height: 50rpx;
  border: 4rpx solid rgba($brand-primary, 0.2);
  border-top-color: $brand-primary;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 100rpx;
}
.empty-img {
  width: 240rpx;
  margin-bottom: 24rpx;
  opacity: 0.6;
}
.empty-text {
  color: $text-tertiary;
  font-size: 28rpx;
}

.check-text {
  font-size: 26rpx;
  color: $text-sub;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(30rpx);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
