<template>
  <scroll-view class="exchange-page" direction="vertical">
    <view class="header">
      <view class="points-info">
        <text class="points-label">可用积分</text>
        <text class="points-value">{{ totalPoints }}</text>
      </view>
      <view class="header-actions">
        <text class="records-link" @click="goToRecords">兑换记录</text>
      </view>
    </view>

    <view class="tabs">
      <view 
        class="tab-item" 
        :class="activeTab === 'all' ? 'active' : ''"
        @click="switchTab('all')"
      >
        <text class="tab-text">全部</text>
      </view>
      <view 
        class="tab-item" 
        :class="activeTab === 'coupon' ? 'active' : ''"
        @click="switchTab('coupon')"
      >
        <text class="tab-text">优惠券</text>
      </view>
      <view 
        class="tab-item" 
        :class="activeTab === 'physical' ? 'active' : ''"
        @click="switchTab('physical')"
      >
        <text class="tab-text">实物</text>
      </view>
      <view 
        class="tab-item" 
        :class="activeTab === 'virtual' ? 'active' : ''"
        @click="switchTab('virtual')"
      >
        <text class="tab-text">虚拟</text>
      </view>
    </view>

    <view class="product-list" v-if="!loading">
      <view 
        class="product-card" 
        v-for="product in filteredProducts" 
        :key="product.id"
        @click="showExchangePopup(product)"
      >
        <image 
          class="product-image" 
          :src="product.image_url != null && product.image_url.length > 0 ? product.image_url : defaultImage" 
          mode="aspectFill"
        />
        <view class="product-info">
          <text class="product-name">{{ product.name }}</text>
          <text class="product-desc" v-if="product.description">{{ product.description }}</text>
          <view class="product-bottom">
            <view class="product-points">
              <text class="points-num">{{ product.points_required }}</text>
              <text class="points-unit">积分</text>
            </view>
            <text class="product-stock">库存{{ product.stock }}件</text>
            <text class="product-original" v-if="product.original_price">¥{{ product.original_price }}</text>
          </view>
        </view>
      </view>
    </view>

    <view class="empty-state" v-if="!loading && filteredProducts.length === 0">
      <text class="empty-text">暂无可兑换商品</text>
    </view>

    <view class="loading-state" v-if="loading">
      <text class="loading-text">加载中...</text>
    </view>

    <view class="exchange-popup" v-if="showPopup" @click="closePopup">
      <view class="popup-content" @click.stop>
        <view class="popup-header">
          <text class="popup-title">确认兑换</text>
          <text class="popup-close" @click="closePopup">×</text>
        </view>
        
        <view class="popup-product" v-if="selectedProduct != null">
          <image 
            class="popup-product-image" 
            :src="selectedProduct.image_url != null && selectedProduct.image_url.length > 0 ? selectedProduct.image_url : defaultImage" 
            mode="aspectFill"
          />
          <view class="popup-product-info">
            <text class="popup-product-name">{{ selectedProduct.name }}</text>
            <view class="popup-product-points">
              <text class="popup-points-num">{{ selectedProduct.points_required }}</text>
              <text class="popup-points-unit">积分</text>
            </view>
          </view>
        </view>

        <view class="popup-quantity">
          <text class="quantity-label">兑换数量</text>
          <view class="quantity-control">
            <text class="quantity-btn" @click="decreaseQuantity">-</text>
            <text class="quantity-value">{{ exchangeQuantity }}</text>
            <text class="quantity-btn" @click="increaseQuantity">+</text>
          </view>
        </view>

        <view class="popup-summary">
          <view class="summary-row">
            <text class="summary-label">消耗积分</text>
            <text class="summary-value">{{ totalPointsCost }}</text>
          </view>
          <view class="summary-row">
            <text class="summary-label">当前积分</text>
            <text class="summary-value">{{ totalPoints }}</text>
          </view>
          <view class="summary-row" v-if="totalPoints < totalPointsCost">
            <text class="summary-label insufficient">积分不足</text>
            <text class="summary-value insufficient">差{{ totalPointsCost - totalPoints }}</text>
          </view>
        </view>

        <button 
          class="popup-btn" 
          :class="{ disabled: totalPoints < totalPointsCost }"
          :disabled="totalPoints < totalPointsCost || exchanging"
          @click="confirmExchange"
        >
          {{ exchanging ? '兑换中...' : '确认兑换' }}
        </button>
      </view>
    </view>

    <view class="success-popup" v-if="showSuccess" @click="closeSuccess">
      <view class="success-content" @click.stop>
        <view class="success-icon">✓</view>
        <text class="success-title">兑换成功</text>
        <text class="success-desc">消耗 {{ totalPointsCost }} 积分</text>
        <button class="success-btn" @click="closeSuccess">确定</button>
      </view>
    </view>
  </scroll-view>
</template>

<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import { supabaseService } from '@/utils/supabaseService.uts'

type PointProduct = {
  id: string
  name: string
  description: string | null
  image_url: string | null
  product_type: string
  points_required: number
  original_price: number | null
  stock: number
  status: number
}

const totalPoints = ref<number>(0)
const products = ref<PointProduct[]>([])
const loading = ref<boolean>(true)
const activeTab = ref<string>('all')
const showPopup = ref<boolean>(false)
const showSuccess = ref<boolean>(false)
const selectedProduct = ref<PointProduct | null>(null)
const exchangeQuantity = ref<number>(1)
const exchanging = ref<boolean>(false)

const defaultImage: string = '/static/images/default.png'

const filteredProducts = computed((): PointProduct[] => {
  if (activeTab.value === 'all') {
    return products.value
  }
  const filtered: PointProduct[] = []
  for (let i = 0; i < products.value.length; i++) {
    if (products.value[i].product_type === activeTab.value) {
      filtered.push(products.value[i])
    }
  }
  return filtered
})

const totalPointsCost = computed((): number => {
  if (selectedProduct.value == null) return 0
  return selectedProduct.value.points_required * exchangeQuantity.value
})

const loadProducts = async (): Promise<void> => {
  loading.value = true
  try {
    const points = await supabaseService.getUserPoints()
    totalPoints.value = points

    const productList = await supabaseService.getPointProducts()
    const parsed: PointProduct[] = []
    for (let i = 0; i < productList.length; i++) {
      const item = productList[i]
      
      let id = ''
      let name = ''
      let description: string | null = null
      let image_url: string | null = null
      let product_type = 'coupon'
      let points_required = 0
      let original_price: number | null = null
      let stock = 0
      let status = 1
      
      let itemObj: UTSJSONObject | null = null
      if (item instanceof UTSJSONObject) {
        itemObj = item
      } else {
        itemObj = JSON.parse(JSON.stringify(item)) as UTSJSONObject
      }
      
      id = itemObj.getString('id') ?? ''
      name = itemObj.getString('name') ?? ''
      description = itemObj.getString('description')
      image_url = itemObj.getString('image_url')
      product_type = itemObj.getString('product_type') ?? 'coupon'
      points_required = itemObj.getNumber('points_required') ?? 0
      original_price = itemObj.getNumber('original_price')
      stock = itemObj.getNumber('stock') ?? 0
      status = itemObj.getNumber('status') ?? 1
      
      const product: PointProduct = {
        id,
        name,
        description,
        image_url,
        product_type,
        points_required,
        original_price,
        stock,
        status
      }
      parsed.push(product)
    }
    products.value = parsed
  } catch (e) {
    console.error('加载商品失败:', e)
  } finally {
    loading.value = false
  }
}

const switchTab = (tab: string): void => {
  activeTab.value = tab
}

const showExchangePopup = (product: PointProduct): void => {
  selectedProduct.value = product
  exchangeQuantity.value = 1
  showPopup.value = true
}

const closePopup = (): void => {
  showPopup.value = false
  selectedProduct.value = null
}

const increaseQuantity = (): void => {
  if (selectedProduct.value != null && exchangeQuantity.value < selectedProduct.value.stock) {
    exchangeQuantity.value++
  }
}

const decreaseQuantity = (): void => {
  if (exchangeQuantity.value > 1) {
    exchangeQuantity.value--
  }
}

const confirmExchange = async (): Promise<void> => {
  if (selectedProduct.value == null) return
  if (totalPoints.value < totalPointsCost.value) return
  
  exchanging.value = true
  
  try {
    const result = await supabaseService.exchangeProduct(
      selectedProduct.value.id,
      exchangeQuantity.value,
      null
    )
    
    if (result.getBoolean('success') === true) {
      showPopup.value = false
      totalPoints.value -= totalPointsCost.value
      showSuccess.value = true
      loadProducts()
    } else {
      const message = result.getString('message') ?? '兑换失败'
      uni.showToast({ title: message, icon: 'none' })
    }
  } catch (e) {
    console.error('兑换异常:', e)
    uni.showToast({ title: '兑换异常', icon: 'none' })
  } finally {
    exchanging.value = false
  }
}

const closeSuccess = (): void => {
  showSuccess.value = false
}

const goToRecords = (): void => {
  uni.navigateTo({
    url: '/pages/mall/consumer/points/exchange-records'
  })
}

onMounted(() => {
  loadProducts()
})
</script>

<style>
.exchange-page {
  flex: 1;
  height: 100%;
  background-color: #f5f5f5;
}

.header {
  background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
  padding: 16px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.points-info {
  display: flex;
  flex-direction: column;
}

.points-label {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.8);
}

.points-value {
  font-size: 28px;
  font-weight: bold;
  color: white;
}

.header-actions {
  display: flex;
  flex-direction: row;
}

.records-link {
  font-size: 14px;
  color: white;
  padding: 6px 12px;
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 16px;
}

.tabs {
  display: flex;
  flex-direction: row;
  background-color: white;
  padding: 0 16px;
}

.tab-item {
  flex: 1;
  padding: 12px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 2px solid transparent;
}

.tab-item.active {
  border-bottom-color: #ff6b35;
}

.tab-text {
  font-size: 14px;
  color: #666;
}

.tab-item.active .tab-text {
  color: #ff6b35;
  font-weight: bold;
}

.product-list {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  padding: 8px;
}

.product-card {
  width: 48%;
  margin: 4px;
  background-color: white;
  border-radius: 8px;
  overflow: hidden;
}

.product-image {
  width: 100%;
  height: 150px;
}

.product-info {
  padding: 8px;
}

.product-name {
  font-size: 14px;
  color: #333;
  lines: 2;
  text-overflow: ellipsis;
}

.product-desc {
  font-size: 12px;
  color: #999;
  margin-top: 4px;
  lines: 1;
  text-overflow: ellipsis;
}

.product-bottom {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  margin-top: 8px;
}

.product-points {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.points-num {
  font-size: 18px;
  font-weight: bold;
  color: #ff6b35;
}

.points-unit {
  font-size: 12px;
  color: #ff6b35;
  margin-left: 2px;
}

.product-stock {
  font-size: 12px;
  color: #ff6b35;
}

.product-original {
  font-size: 12px;
  color: #999;
}

.empty-state {
  padding: 60px 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.empty-text {
  font-size: 14px;
  color: #999;
}

.loading-state {
  padding: 60px 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-text {
  font-size: 14px;
  color: #999;
}

.exchange-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 1000;
}

.popup-content {
  background-color: white;
  border-radius: 16px 16px 0 0;
  width: 100%;
  padding: 16px;
}

.popup-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.popup-title {
  font-size: 18px;
  font-weight: bold;
  color: #333;
}

.popup-close {
  font-size: 24px;
  color: #999;
}

.popup-product {
  display: flex;
  flex-direction: row;
  padding: 12px;
  background-color: #f9f9f9;
  border-radius: 8px;
  margin-bottom: 16px;
}

.popup-product-image {
  width: 80px;
  height: 80px;
  border-radius: 4px;
}

.popup-product-info {
  flex: 1;
  margin-left: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.popup-product-name {
  font-size: 14px;
  color: #333;
  lines: 2;
}

.popup-product-points {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-top: 8px;
}

.popup-points-num {
  font-size: 20px;
  font-weight: bold;
  color: #ff6b35;
}

.popup-points-unit {
  font-size: 12px;
  color: #ff6b35;
  margin-left: 2px;
}

.popup-quantity {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid #f0f0f0;
}

.quantity-label {
  font-size: 14px;
  color: #333;
}

.quantity-control {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.quantity-btn {
  width: 28px;
  height: 28px;
  background-color: #f5f5f5;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  color: #666;
}

.quantity-value {
  width: 40px;
  text-align: center;
  font-size: 16px;
  color: #333;
}

.popup-summary {
  padding: 12px 0;
}

.summary-row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.summary-label {
  font-size: 14px;
  color: #666;
}

.summary-label.insufficient {
  color: #ff6b35;
}

.summary-value {
  font-size: 14px;
  color: #333;
}

.summary-value.insufficient {
  color: #ff6b35;
}

.popup-btn {
  background: linear-gradient(135deg, #ff6b35 0%, #ff8c42 100%);
  color: white;
  font-size: 16px;
  font-weight: bold;
  border-radius: 24px;
  height: 44px;
  line-height: 44px;
  margin-top: 16px;
}

.popup-btn.disabled {
  background: #ccc;
}

.success-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1001;
}

.success-content {
  background-color: white;
  border-radius: 16px;
  padding: 32px;
  width: 280px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.success-icon {
  width: 60px;
  height: 60px;
  background-color: #52c41a;
  border-radius: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  color: white;
  margin-bottom: 16px;
}

.success-title {
  font-size: 20px;
  font-weight: bold;
  color: #333;
  margin-bottom: 8px;
}

.success-desc {
  font-size: 14px;
  color: #666;
  margin-bottom: 24px;
}

.success-btn {
  background-color: #ff6b35;
  color: white;
  font-size: 16px;
  border-radius: 20px;
  width: 100%;
  height: 40px;
  line-height: 40px;
}
</style>
