<template>
  <view class="product-list-container">
    <u-sticky bgColor="#ffffff">
      <!-- 商品列表头部 -->
      <view class="product-header">
        <view class="title-text" :class="{ 'hide': isSticky }"><text>精选好物</text>兑换</view>
        <u-search placeholder="搜索" v-model="keyword" :showAction="false" :class="{ 'expand': isSticky }" @search="loadData"></u-search>
      </view>
    
      <!-- 分类标签 -->
      <u-tabs
        :list="categories"
        :current="activeCategoryIndex"
        @change="handleCategoryChange"
        lineWidth="30"
        :scrollable="categories.length > 5 ? true : false"
        lineColor="#20CAC2"
        :activeStyle="{
              color: '#303133',
              fontWeight: 'bold',
              transform: 'scale(1.05)'
          }"
        :inactiveStyle="{
              color: '#606266',
              transform: 'scale(1)'
          }"
        itemStyle="padding:0 43rpx; height: 72rpx;font-size:28rpx"
        class="category-tabs"
      ></u-tabs>
    
      <!-- 排序选项 -->
      <view class="sort-options">
        <view
          v-for="(sort, index) in sortOptions"
          :key="index"
          class="sort-option"
          @click="switchSort(sort.key)"
        >
          <text :class="['sort-text', { active: activeSort === sort.key }]">{{ sort.name }}</text>
          <view v-if="['price','sales'].includes(sort.key)" style="margin-top: -8rpx;">
            <ImageItem src="/static/points/arrow-up.png" v-if="activeSort === sort.key && sortDirection === 'asc'"></ImageItem>
            <ImageItem src="/static/points/arrow-down.png" v-else-if="activeSort === sort.key && sortDirection === 'desc'"></ImageItem>
            <ImageItem src="/static/points/details.png" v-else></ImageItem>
          </view>
        </view>
      </view>
    </u-sticky>
    <!-- 商品列表 -->
    <u-loading-icon text="加载中" textSize="18" v-if="status === 'loading' && products.length <= 0" style="margin-top: 200rpx;"/>
    <view class="product-grid" v-else-if="products.length > 0">
      <view class="product-item" v-for="(product, index) in products" :key="index" @click="handleExchange(product)">
        <view class="product-image">
          <view v-if="!imageErrorMap[product.id]" class="product-image">
            <ImageItem 
              :src="getImageUrl(product.productMainImage)"
              @image-error="handleImageError(product.id)"
            />
          </view>
          <view v-else style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 248rpx; background-color: #f5f5f5; border-radius: 8rpx;">
            <uni-icons type="image" size="64rpx" color="#999" @click="resetImageError(product.id)"></uni-icons>
            <text style="font-size: 24rpx; color: #999; margin-top: 16rpx;">加载失败</text>
          </view>
        </view>
        <view class="product-info">
          <u--text class="product-name" :lines="1" :text="product.name"></u--text>
          <text class="product-price" v-if="product.paymentType == 1">{{ product.pricePoint }}积分</text>
          <text class="product-price" v-if="product.paymentType == 2">¥{{ product.priceMoney }}</text>
          <text class="product-price" v-if="product.paymentType == 3">¥{{ product.priceMoney }}+{{ product.pricePoint }}积分</text>
          <view class="product-details">
            <view class="product-detail">
              <text class="product-value">价值{{ product.originalPrice }}元</text>
              <text class="product-sales">销量{{ product.sales }}</text>
            </view>
            <button class="exchange-btn" @click="handleExchange(product)">
              兑换
            </button>
          </view>
        </view>
      </view>
    </view>
    <u-loadmore :status="status" loading-text="努力加载中" nomore-text="没有更多了" lineColor="#E6E8EB" v-if="products.length > 0"/>
    <u-empty
        style="margin-top:100rpx"
        v-if="products.length <= 0 && status !== 'loading'"
        icon="car-fill"
        text="暂无积分商品"
    >
    </u-empty>
  </view>
</template>

<script>
import ImageItem from "@/components/swiper/components/image.vue";
import {getShopType,getPointShopList} from "@/api/shop";
export default {
  components: {ImageItem},
  props: {
    // 从父组件传递的滚动距离
    scrollTop: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      // 搜索关键词
      keyword: '',
      // 分类数据
      activeCategory: '',
      categories: [],
      // 排序选项
      sortOptions: [
        { key: 'comprehensive', name: '综合' },
        { key: 'price', name: '价格' },
        { key: 'sales', name: '销量' }
      ],
      activeSort: 'comprehensive',
      sortDirection: '',
      // 商品数据
      products:[],
      // 分页数据
      page: 1,
      pageSize: 10,
      status:'more',
      hasMore: true,
      // 吸顶状态
      isSticky: false,
      // 吸顶元素的初始位置
      stickyTop: 0,
      // 图片加载状态
      imageErrorMap: {}
    }
  },
  mounted() {
    this.getTypeShop();
    this.loadData()
    // 延迟获取吸顶元素的初始位置，确保DOM已经渲染完成
    this.$nextTick(() => {
      this.getStickyTop()
    })
  },
  watch: {
    // 监听滚动距离的变化
    scrollTop(newVal) {
      // 判断是否进入吸顶状态
      this.isSticky = newVal >= this.stickyTop
    }
  },
  methods: {
    //获取分类
    async getTypeShop() {
      const res = await getShopType();
      const {data} = res.data;
      this.categories = [
        { key: '', name: '全部' },
        ...(Array.isArray(data) ? data.map(item => {
          return {
            name: item.childName,
            key: item.childId
          }
        }) : [])
      ]
    },
    // 获取吸顶元素的初始位置
    getStickyTop() {
      const query = uni.createSelectorQuery().in(this)
      query.select('.product-header').boundingClientRect(data => {
        if (data) {
          this.stickyTop = data.top
        }
      }).exec()
    },
    // 加载商品数据
    fetchProducts(page) {
      return getPointShopList({
        current: page,
        size: this.pageSize,
        name:this.keyword,
        categoryId: this.activeCategory,
        sortField: this.activeSort,
        sortOrder: this.sortDirection
      })
    },
    // 加载初始数据
    loadData() {
      this.status = 'loading'
      this.fetchProducts(1).then(res => {
        const {data} = res;
        console.log(res)
        if (data.code === 200) {
          this.products = data.data.records
          this.hasMore = data.data.records.length === this.pageSize
          this.status = this.hasMore ? 'more' : 'nomore'
        } else {
          this.status = 'error'
        }
      }).catch(err => {
        console.error('加载商品列表失败:', err)
        this.status = 'error'
      })
    },
    // 处理分类切换
    handleCategoryChange(data) {
      this.activeCategory = data.key
      //重置页码
      this.page = 1
      // 等待DOM更新后再加载数据
      this.$nextTick(() => {
        this.loadData()
      })
    },
    // 切换排序
    switchSort(sort) {
      if (this.activeSort === sort) {
        // 如果点击的是当前排序，切换排序方向
        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc'
      } else {
        // 如果点击的是新排序，设置默认排序方向
        this.activeSort = sort
        // 价格和销量默认排序方向为asc
        if (['price', 'sales'].includes(sort)) {
          this.sortDirection = 'asc'
        } else {
          this.sortDirection = ''
        }
      }
      // 重置页码
      this.page = 1
      // 等待DOM更新后再加载数据
      this.$nextTick(() => {
        this.loadData()
      })
    },
    // 处理兑换
    handleExchange(product) {
      uni.navigateTo({
        url: `/points/productDetails/index?id=${product.id}`
      });
      console.log('兑换商品:', product)
    },
    // 加载更多
    loadMore() {
      if (this.status === 'loading' || !this.hasMore) return
      this.status = 'loading'
      this.page++
      this.fetchProducts(this.page).then(res => {
        const {data} = res;
        if (data.code === 200) {
          const newProducts = data.data.records
          this.products = [...this.products, ...newProducts]
          this.hasMore = newProducts.length === this.pageSize
          this.status = this.hasMore ? 'more' : 'nomore'
        } else {
          this.status = 'error'
        }
      }).catch(err => {
        console.error('加载更多商品失败:', err)
        this.status = 'error'
      })
    },
    // 获取图片 URL
    getImageUrl(imagePath) {
      if (!imagePath) return '';
      const publicUrl = this.$globalData?.publicUrl || '';
      return publicUrl + imagePath;
    },
    // 处理图片加载失败
    handleImageError(productId) {
      this.$set(this.imageErrorMap, productId, true);
    },
    // 重置图片加载状态
    resetImageError(productId) {
      this.$set(this.imageErrorMap, productId, false);
    },
  },
  computed: {
    activeCategoryIndex() {
      return this.categories.findIndex(item => item.key === this.activeCategory)
    }
  },
}
</script>

<style lang="scss" scoped>
.product-list-container {
  width: 750rpx;
  background: #FFFFFF;
  border-radius: 20rpx 20rpx 0 0;
  padding-bottom: 32rpx;
  margin-top: -20rpx;
  overflow: clip;
  .product-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 24rpx 32rpx 0 32rpx;
    background-color: #fff;
    transition: all 0.3s ease;
    height: 90rpx;
    .title-text {
      font-size: 32rpx;
      font-weight: 600;
      color: #333;
      margin-right: 22rpx;
      text{
        color: #20CAC2;
        margin-right: 4rpx;
      }
      transition: all 0.3s ease;
      &.hide {
        opacity: 0;
        transform: translateX(-20rpx);
        width: 0;
        margin-right: 0;
        overflow: hidden;
      }
    }
    
    .search-icon {
      margin-right: 8rpx;
    }
    
    :deep(.u-search) {
      flex: 1;
      max-width: 300rpx;
      transition: all 0.3s ease;
      &.expand {
        max-width: 100%;
      }
    }
  }
  
  .category-tabs {
    background-color: #fff;
    border-bottom: 1rpx solid #f0f0f0;
  }
  
  .sort-options {
    display: flex;
    justify-content: space-around;
    padding: 16rpx 32rpx;
    background-color: #fff;
    border-bottom: 1rpx solid #F5F5F5;
    
    .sort-option {
      display: flex;
      align-items: center;
      justify-content: center;
      flex: 1;
      
      .sort-text {
        font-size: 28rpx;
        color: #666;
        
        &.active {
          color: #03C8BE;
        }
      }
      
      image {
        margin-left: 4rpx;
        width: 20rpx;
        height: 20rpx;
      }
    }
  }
  
  .product-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap: 24rpx;
    padding: 24rpx 32rpx;
    .product-item {
      width: 324rpx;
      background-color: #fff;
      border-radius: 12rpx;
      overflow: hidden;
      box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
      
      .product-image {
        width: 100%;
        height: 248rpx;
        overflow: hidden;
        
        image {
          width: 100%;
          height: 100%;
        }
      }
      
      .product-info {
        padding: 14rpx 16rpx;
        .product-name {
          font-family: PingFang SC, PingFang SC;
          font-weight: 500;
          font-size: 28rpx;
          color: #333333;
          display: block;
          margin-bottom: 16rpx!important;
        }
        
        .product-price {
          font-family: PingFang SC, PingFang SC;
          font-weight: 500;
          font-size: 32rpx;
          color: #F53E54;
          display: block;
          margin-bottom: 16rpx;
        }
        .product-details{
          display: flex;
          justify-content: space-between;
          align-items: center;
          .product-detail{
            .product-value {
              display: block;
              font-size: 24rpx;
              color: #999999;
              margin-bottom: 18rpx;
            }

            .product-sales {
              display: block;
              font-size: 24rpx;
              color: #999999;
            }
          }
          .exchange-btn {
            width: 120rpx;
            height: 48rpx;
            background: linear-gradient( 78deg, #1AD8CF 0%, #21C8C0 100%);
            border-radius: 98rpx;
            font-size: 28rpx;
            color: #FFFFFF;
            text-align: center;
            line-height: 48rpx;
            margin: 20rpx 0 0 0;
            padding: 0;
          }
        }
      }
    }
  }
}
</style>