<!-- 消费者端 - 个人中心 -->
<template>
  <view class="consumer-profile" :style="profilePageStyle">
    <scroll-view class="profile-scroll-content" :style="profileScrollStyle" :scroll-y="true" :lower-threshold="120" @scroll="onRecommendScroll" @scrolltolower="onRecommendScrollToLower">
      <view class="profile-page-inner">
        <view class="jd-profile-top" :class="{ 'jd-profile-top-android': isAndroidApp }" :style="{ paddingTop: statusBarHeight + 'px' }">
          <view class="jd-user-header" :style="{ marginTop: userHeaderTopOffset + 'px', paddingRight: userHeaderRightReserve + 'px' }">
            <view class="jd-user-brief" @click="editProfile">
              <image :src="userInfo.avatar_url != '' ? userInfo.avatar_url : '/static/images/default.png'" class="jd-user-avatar" mode="aspectFill" />
              <view class="jd-user-texts">
                <view class="jd-user-name-row">
                  <text class="jd-user-name">{{ userInfo.nickname != '' ? userInfo.nickname : (userInfo.phone != '' ? userInfo.phone : '立即登录') }}</text>
                </view>

                <view class="jd-user-tag-row">
                  <text class="jd-user-tag">{{ getUserLevel() + ' >' }}</text>
                  <text class="jd-user-tag jd-user-tag-secondary">{{ userInfo.phone != '' ? '账号资料 >' : '完善个人资料 >' }}</text>
                </view>
              </view>
            </view>
          </view>

          <view class="capsule-below-actions" :style="{ top: topActionsTop + 'px', right: topActionsRight + 'px', width: topActionsWidth + 'px' }">
            <view class="capsule-action-item" @click.stop="goToAddress">
              <image v-if="addressIconPath != ''" class="capsule-action-icon" :src="addressIconPath" mode="aspectFit" />
              <text v-else class="capsule-action-fallback">址</text>
              <text class="capsule-action-text">地址</text>
            </view>

            <view class="capsule-action-item" @click.stop="goToSettings">
              <image v-if="settingIconPath != ''" class="capsule-action-icon" :src="settingIconPath" mode="aspectFit" />
              <text v-else class="capsule-action-fallback">设</text>
              <text class="capsule-action-text">设置</text>
            </view>
          </view>

          <view class="jd-wallet-card">
            <view class="wallet-plus-ribbon" :class="{ 'wallet-plus-ribbon-android': isAndroidApp }">
              <view class="wallet-plus-left-oval"></view>
            </view>

            <view class="wallet-title-block" @click="goToWallet">
              <text class="wallet-title-text">我的钱包</text>
              <text class="wallet-title-arrow">›</text>
            </view>

            <view class="wallet-curve-cover"></view>

            <view class="wallet-plus-content" @click="goToMember">
              <text class="wallet-crown-icon">♛</text>
              <text class="wallet-plus-title">{{ getUserLevel() }}</text>
              <text class="wallet-plus-desc">会员福利仅在此</text>
              <view class="wallet-plus-arrow">
                <text class="wallet-plus-arrow-text">›</text>
              </view>
            </view>

            <view class="wallet-assets-row">
              <view class="wallet-asset-item" @click="goToPoints">
                <text class="wallet-asset-value">{{ userStats.points }}</text>
                <text class="wallet-asset-label">积分</text>
              </view>

              <view class="wallet-asset-item" @click="goToBalance">
                <text class="wallet-asset-value">¥{{ userStats.balance }}</text>
                <text class="wallet-asset-label">余额</text>
              </view>

              <view class="wallet-asset-item" @click="goToCoupons">
                <text class="wallet-asset-value">{{ serviceCounts.coupons }}</text>
                <text class="wallet-asset-label">优惠券</text>
              </view>

              <view class="wallet-asset-item" @click="goToMember">
                <text class="wallet-asset-value">8折</text>
                <text class="wallet-asset-label">会员权益</text>
              </view>
            </view>

            <view class="wallet-more-entry" @click="goToWallet">
              <text class="wallet-more-text">更多</text>
              <view class="wallet-more-circle">
                <text class="wallet-more-arrow">›</text>
              </view>
            </view>
          </view>
        </view>

        <view class="order-shortcuts order-card">
          <view class="order-header">
            <text class="order-title">我的订单</text>
            <view class="order-all-link" @click="goToOrders('all')">
              <text class="card-link">全部</text>
              <text class="order-all-arrow">›</text>
            </view>
          </view>
          <view class="order-actions">
            <view class="order-action" :class="{ active: currentOrderTab === 'pending' }" @click="openOrderAction('pending', 'pending')">
              <view class="order-icon-wrap">
                <image class="order-icon-img" src="/static/consumer/payment.png" mode="aspectFit" />
                <text v-if="orderCounts.pending > 0" class="order-badge">{{ formatOrderBadgeCount(orderCounts.pending) }}</text>
              </view>
              <text class="order-action-text">待付款</text>
            </view>
            <view class="order-action" @click="goToRefund">
              <view class="order-icon-wrap">
                <image class="order-icon-img" src="/static/consumer/refund_quota.png" mode="aspectFit" />
              </view>
              <text class="order-action-text">售后/退换</text>
            </view>
            <view class="order-action" :class="{ active: currentOrderTab === 'shipped' }" @click="openOrderAction('shipped', 'shipped')">
              <view class="order-icon-wrap">
                <image class="order-icon-img" src="/static/consumer/receipt.png" mode="aspectFit" />
                <text v-if="orderCounts.shipped > 0" class="order-badge">{{ formatOrderBadgeCount(orderCounts.shipped) }}</text>
              </view>
              <text class="order-action-text">待收货</text>
            </view>
            <view class="order-action" :class="{ active: currentOrderTab === 'review' }" @click="openOrderAction('review', 'review')">
              <view class="order-icon-wrap">
                <image class="order-icon-img" src="/static/consumer/comment.png" mode="aspectFit" />
                <text v-if="orderCounts.review > 0" class="order-badge">{{ formatOrderBadgeCount(orderCounts.review) }}</text>
              </view>
              <text class="order-action-text">待评价</text>
            </view>
          </view>
          <view v-if="pendingReceiptGoods != null" class="pending-receipt-strip" @click="openOrderAction('shipped', 'shipped')">
            <image class="pending-goods-img" :src="pendingReceiptGoods.image" mode="aspectFill" />
            <view class="pending-goods-info">
              <view class="pending-goods-title-row">
                <text class="pending-status">待收货</text>
                <text class="pending-desc">{{ pendingReceiptGoods.statusText }}</text>
              </view>
              <text class="pending-goods-name">{{ pendingReceiptGoods.name }}</text>
            </view>
            <text class="pending-arrow">›</text>
          </view>
        </view>

        <view class="my-services service-card">
          <scroll-view class="service-scroll" direction="horizontal" scroll-x="true" :scroll-y="false" :show-scrollbar="false" scroll-with-animation>
            <view class="service-row">
              <view class="service-item" @click="goToMessages">
                <view class="service-icon-wrap">
                  <text class="service-text-icon">聊</text>
                  <text v-if="serviceCounts.unreadMessages > 0" class="service-badge">{{ serviceCounts.unreadMessages }}</text>
                </view>
                <text class="service-name">消息中心</text>
              </view>
              <view class="service-item" @click="goToCoupons">
                <view class="service-icon-wrap">
                  <image class="service-icon-img" src="/static/consumer/coupon.png" mode="aspectFit" />
                  <text v-if="serviceCounts.coupons > 0" class="service-badge">{{ serviceCounts.coupons }}</text>
                </view>
                <text class="service-name">优惠券</text>
              </view>
              <view class="service-item" @click="goToAddress">
                <view class="service-icon-wrap">
                  <text class="service-text-icon">址</text>
                </view>
                <text class="service-name">收货地址</text>
              </view>
              <view class="service-item" @click="goToFavorites">
                <view class="service-icon-wrap">
                  <image class="service-icon-img" src="/static/consumer/collection.png" mode="aspectFit" />
                  <text v-if="serviceCounts.favorites > 0" class="service-badge">{{ serviceCounts.favorites }}</text>
                </view>
                <text class="service-name">商品收藏</text>
              </view>
              <view class="service-item" @click="goToFootprint">
                <view class="service-icon-wrap">
                  <image class="service-icon-img" src="/static/consumer/footprint.png" mode="aspectFit" />
                </view>
                <text class="service-name">浏览足迹</text>
              </view>
              <view class="service-item" @click="goToRefund">
                <view class="service-icon-wrap">
                  <text class="service-text-icon">退</text>
                </view>
                <text class="service-name">退款售后</text>
              </view>
              <view class="service-item" @click="goToOrderReviews">
                <view class="service-icon-wrap">
                  <text class="service-text-icon">评</text>
                </view>
                <text class="service-name">我的评价</text>
              </view>
              <view class="service-item" @click="goToFollowedShops">
                <view class="service-icon-wrap">
                  <image class="service-icon-img" src="/static/consumer/store.png" mode="aspectFit" />
                </view>
                <text class="service-name">关注店铺</text>
              </view>
              <view class="service-row-end-spacer"></view>
            </view>
          </scroll-view>
        </view>

        <GuessYouLike
          title="猜你喜欢"
          :pageSize="8"
          :loadMoreKey="guessLoadMoreKey"
          @productClick="handleGuessProductClick"
        />

        <view class="profile-bottom-safe"></view>
      </view>
    </scroll-view>

    <view v-if="!isLoggedIn" class="guest-login-bar">
      <view class="guest-login-left">
        <image class="guest-login-avatar" src="/static/images/default.png" mode="aspectFit" />
        <text class="guest-login-text">登录一下，康养权益和订单记录同步保存～</text>
      </view>
      <button class="guest-login-btn" @click.stop="goProfileLogin">立即登录</button>
    </view>
  </view>
</template>

<script>
import { UserType } from '@/types/mall-types.uts'
import supabaseService from '@/utils/supabaseService.uts'
import { goToLogin } from '@/utils/utils.uts'
import GuessYouLike from '@/components/mall/GuessYouLike/GuessYouLike.uvue'

type UserStatsType = {
  points: number
  balance: number
  level: number
}

type OrderCountsType = {
  total: number
  pending: number
  toship: number
  shipped: number
  review: number
}

type ServiceCountsType = {
  coupons: number
  favorites: number
  unreadMessages: number
}

type ConsumptionStatsType = {
  total_amount: number
  order_count: number
  avg_amount: number
  save_amount: number
}

type StatsPeriodType = {
  key: string
  label: string
}

type OrderItemType = {
  id: string
  order_no: string
  status: number
  actual_amount: number
  created_at: string
  ml_order_items: any | null
  ml_shops: any | null
  items_count: number
}

type RecommendProductType = {
  id: string
  name: string
  price: number
  image: string
  tag: string
}

type PendingReceiptGoodsType = {
  image: string
  statusText: string
  name: string
}

type ModalSuccessResult = { confirm: boolean; cancel: boolean }

export default {
  components: {
    GuessYouLike
  },
  data() {
    return {
      userInfo: {
        id: '',
        phone: '',
        email: '',
        nickname: '',
        avatar_url: '',
        gender: 0,
        user_type: 0,
        status: 0,
        created_at: ''
      } as UserType,
      userStats: {
        points: 0,
        balance: 0,
        level: 0
      } as UserStatsType,
      orderCounts: {
        total: 0,
        pending: 0,
        toship: 0,
        shipped: 0,
        review: 0
      } as OrderCountsType,
      serviceCounts: {
        coupons: 0,
        favorites: 0,
        unreadMessages: 0
      } as ServiceCountsType,
      recentOrders: [] as Array<OrderItemType>,
      statsPeriods: [
        { key: 'month', label: '本月' },
        { key: 'quarter', label: '本季度' },
        { key: 'year', label: '本年' },
        { key: 'all', label: '全部' }
      ] as Array<StatsPeriodType>,
      activeStatsPeriod: 'month',
      currentStats: {
        total_amount: 0,
        order_count: 0,
        avg_amount: 0,
        save_amount: 0
      } as ConsumptionStatsType,
      recommendProducts: [] as Array<RecommendProductType>,
      recommendPage: 1,
      recommendPageSize: 8,
      recommendLoading: false,
      recommendHasMore: true,
      recommendInitialized: false,
      lastRecommendLoadTime: 0,
      recommendPendingLoad: false,
      recommendBottomLocked: false,
      recommendViewportHeight: 0,
      pageWindowHeight: 0,
      isLoggedIn: false,
      guessLoadMoreKey: 0,
      statusBarHeight: 0,
      isAndroidApp: false,
      capsuleTop: 0,
      capsuleBottom: 0,
      capsuleLeft: 0,
      capsuleRight: 0,
      capsuleWidth: 0,
      capsuleHeight: 0,
      capsuleRightGap: 16,
      heroContentTop: 0,
      topActionsTop: 0,
      topActionsRight: 16,
      topActionsWidth: 104,
      userHeaderRightReserve: 118,
      userHeaderTopOffset: 0,
      addressIconPath: '/static/location.png',
      settingIconPath: '/static/setting.png',
      navBarRight: 0, // 导航栏右侧预留空间（小程序胶囊按钮）
      currentOrderTab: 'all' as string,
      pendingReceiptGoods: {
        image: '/static/consumer/receipt.png',
        statusText: '商品运输中',
        name: '您有 1 件商品正在配送，请注意查收'
      } as PendingReceiptGoodsType | null,
      allOrders: [] as Array<OrderItemType>
    }
  },
  onLoad() {
    this.initPage()
    this.refreshLoginState()
    this.loadUserProfile()
    this.loadOrders()
    
    // 监听订单更新事件
    uni.$on('orderUpdated', this.handleOrderUpdated)
    uni.$on('authChanged', this.handleAuthChanged)
  },
  onShow() {
    this.refreshLoginState()
    this.refreshData()
  },
  onUnload() {
    // 移除事件监听
    uni.$off('orderUpdated', this.handleOrderUpdated)
    uni.$off('authChanged', this.handleAuthChanged)
  },
  computed: {
    filteredOrders(): Array<OrderItemType> {
      const result: Array<OrderItemType> = []
      if (this.currentOrderTab === 'all') {
        for (let i: number = 0; i < this.allOrders.length; i++) {
          result.push(this.allOrders[i])
        }
        return result
      }
      let targetStatus: number = 0
      if (this.currentOrderTab === 'pending') {
        targetStatus = 1
      } else if (this.currentOrderTab === 'toship') {
        targetStatus = 2
      } else if (this.currentOrderTab === 'shipped') {
        targetStatus = 3
      } else if (this.currentOrderTab === 'review') {
        targetStatus = 4
      } else {
        return result
      }
      for (let i: number = 0; i < this.allOrders.length; i++) {
        if (this.allOrders[i].status === targetStatus) {
          result.push(this.allOrders[i])
        }
      }
      return result
    },
    profilePageStyle(): string {
      return this.getProfilePageStyle()
    },
    profileScrollStyle(): string {
      return this.getProfileScrollStyle()
    }
  },
  methods: {
    refreshLoginState() {
      const userId = supabaseService.getCurrentUserId()
      this.isLoggedIn = userId != null && userId !== ''
    },

    toRecommendScrollJson(value: any | null): UTSJSONObject | null {
      if (value == null) {
        return null
      }
      if (value instanceof UTSJSONObject) {
        return value as UTSJSONObject
      }
      const raw = JSON.stringify(value)
      if (raw === '' || raw === 'null') {
        return null
      }
      const parsed = JSON.parse(raw)
      if (parsed == null) {
        return null
      }
      return parsed as UTSJSONObject
    },

    readRecommendScrollMetric(detail: UTSJSONObject | null, key: string): number {
      if (detail == null) {
        return 0
      }
      const value = detail.getNumber(key)
      if (value != null) {
        return value
      }
      return 0
    },

    mergeRecommendProducts(oldList: Array<RecommendProductType>, newList: Array<RecommendProductType>): Array<RecommendProductType> {
      const ids: Array<string> = []
      const result: Array<RecommendProductType> = []

      for (let i: number = 0; i < oldList.length; i++) {
        ids.push(oldList[i].id)
        result.push(oldList[i])
      }

      for (let i: number = 0; i < newList.length; i++) {
        if (ids.indexOf(newList[i].id) < 0) {
          ids.push(newList[i].id)
          result.push(newList[i])
        }
      }

      return result
    },

    async fetchRecommendProducts(page: number, pageSize: number): Promise<Array<RecommendProductType>> {
      console.log('[profile推荐] fetchRecommendProducts 请求 page=', page, 'pageSize=', pageSize)
      const result = await supabaseService.searchProducts('', page, pageSize, 'sales')
      console.log('[profile推荐] fetchRecommendProducts 完成 total=', result.total, 'hasmore=', result.hasmore, 'dataLength=', result.data.length)
      const rawList = result.data as any[]
      const list: Array<RecommendProductType> = []
      for (let i: number = 0; i < rawList.length; i++) {
        const productObj = JSON.parse(JSON.stringify(rawList[i])) as UTSJSONObject
        const productId = productObj.getString('id') ?? ''
        if (productId === '') {
          continue
        }
        const basePrice = productObj.getNumber('base_price')
        const marketPrice = productObj.getNumber('market_price')
        const mainImage = productObj.getString('main_image_url')
        const fallbackImage = productObj.getString('image_url')
        const sales = productObj.getNumber('sales')
        list.push({
          id: productId,
          name: productObj.getString('name') ?? '精选商品',
          image: mainImage != null && mainImage !== '' ? mainImage : (fallbackImage != null && fallbackImage !== '' ? fallbackImage : '/static/images/default.png'),
          price: basePrice != null ? basePrice : (marketPrice != null ? marketPrice : 0),
          tag: sales != null && sales > 0 ? ('已售' + sales) : '猜你喜欢'
        } as RecommendProductType)
      }
      return list
    },

    async loadRecommendProducts(reset: boolean) {
      console.log('[profile推荐] loadRecommendProducts 入口 reset=', reset, 'page=', this.recommendPage, 'pageSize=', this.recommendPageSize, 'loading=', this.recommendLoading, 'hasMore=', this.recommendHasMore, 'oldLength=', this.recommendProducts.length)
      if (this.recommendLoading) {
        console.log('[profile推荐] 跳过：正在加载中')
        if (!reset) {
          this.recommendPendingLoad = true
        }
        return
      }
      if (!reset && !this.recommendHasMore) {
        console.log('[profile推荐] 跳过：没有更多数据')
        return
      }
      if (!reset) {
        this.lastRecommendLoadTime = Date.now()
      }

      this.recommendLoading = true

      if (reset) {
        this.recommendPage = 1
        this.recommendHasMore = true
      }

      try {
        const page = this.recommendPage
        const pageSize = this.recommendPageSize
        const newList = await this.fetchRecommendProducts(page, pageSize)
        console.log('[profile推荐] page=', page, '返回数量=', newList.length)
        console.log('[profile推荐] 返回ID=', newList.map((item) => item.id).join(','))

        const beforeLength = this.recommendProducts.length
        let afterList: Array<RecommendProductType> = []

        if (reset) {
          afterList = newList
        } else {
          afterList = this.mergeRecommendProducts(this.recommendProducts, newList)
        }
        this.recommendProducts = afterList
        console.log('[profile推荐] 追加前=', beforeLength, '追加后=', this.recommendProducts.length)
        if (!reset && newList.length > 0 && afterList.length === beforeLength) {
          console.warn('[profile推荐] 本次返回商品全部重复，请检查 searchProducts 分页是否生效 page=', page)
        }

        if (newList.length < pageSize) {
          this.recommendHasMore = false
        } else {
          this.recommendPage = this.recommendPage + 1
        }

        if (!reset) {
          this.recommendBottomLocked = false
        }

        this.recommendInitialized = true
      } catch (e) {
        console.error('加载推荐商品失败:', e)
        this.recommendHasMore = false
      } finally {
        this.recommendLoading = false
        if (!reset && this.recommendPendingLoad && this.recommendHasMore) {
          console.log('[profile推荐] 消费待续加载请求')
          this.recommendPendingLoad = false
          this.loadRecommendProducts(false)
        }
      }
    },

    onRecommendScrollToLower() {
      this.guessLoadMoreKey = this.guessLoadMoreKey + 1
    },

    onRecommendScroll(event: any) {
      return
    },

    handleGuessProductClick(productId: string) {
      if (productId == null || productId === '') {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/product-detail?id=${productId}&productId=${productId}`
      })
    },

    resetGuestProfileState() {
      this.userInfo = {
        id: '',
        phone: '',
        email: '',
        nickname: '立即登录',
        avatar_url: '',
        gender: 0,
        user_type: 0,
        status: 0,
        created_at: ''
      } as UserType

      this.userStats = {
        points: 0,
        balance: 0,
        level: 0
      } as UserStatsType

      this.serviceCounts = {
        coupons: 0,
        favorites: 0,
        unreadMessages: 0
      } as ServiceCountsType

      this.orderCounts = {
        total: 0,
        pending: 0,
        toship: 0,
        shipped: 0,
        review: 0
      } as OrderCountsType

      this.recentOrders = [] as Array<OrderItemType>
      this.allOrders = [] as Array<OrderItemType>
      this.currentOrderTab = 'all'
      this.pendingReceiptGoods = null
    },

    async loadOrders() {
      const userId = supabaseService.getCurrentUserId()
      if (userId == null || userId === '') {
        this.orderCounts = {
          total: 0,
          pending: 0,
          toship: 0,
          shipped: 0,
          review: 0
        } as OrderCountsType
        this.recentOrders = [] as Array<OrderItemType>
        this.allOrders = [] as Array<OrderItemType>
        this.pendingReceiptGoods = null
        return
      }

      try {
        const orders = await supabaseService.getOrders()
        
        const mappedOrders: Array<OrderItemType> = []
        for (let i: number = 0; i < orders.length; i++) {
          const rawItem = orders[i]
          const o = JSON.parse(JSON.stringify(rawItem)) as UTSJSONObject
          
          let status = o.getNumber('status')
          if (status == null) {
            const orderStatus = o.getNumber('order_status')
            status = orderStatus != null ? orderStatus : 0
          }
          
          let actualAmount = o.getNumber('actual_amount')
          if (actualAmount == null) {
            const totalAmount = o.getNumber('total_amount')
            actualAmount = totalAmount != null ? totalAmount : 0
          }
          
          const mlOrderItems = o.get('ml_order_items')
          
          let itemsCount = 0
          if (mlOrderItems != null && Array.isArray(mlOrderItems)) {
            itemsCount = (mlOrderItems as any[]).length
          }
          
          const orderItem: OrderItemType = {
            id: o.getString('id') ?? '',
            order_no: o.getString('order_no') ?? '',
            status: status,
            actual_amount: actualAmount,
            created_at: o.getString('created_at') ?? '',
            ml_order_items: mlOrderItems,
            ml_shops: o.get('ml_shops'),
            items_count: itemsCount
          }
          
          mappedOrders.push(orderItem)
        }
        
        for (let i: number = 0; i < mappedOrders.length; i++) {
          for (let j: number = i + 1; j < mappedOrders.length; j++) {
            const dateA = mappedOrders[i]['created_at'] as string
            const dateB = mappedOrders[j]['created_at'] as string
            const timeA = new Date(dateA != null ? dateA : '1970-01-01').getTime()
            const timeB = new Date(dateB != null ? dateB : '1970-01-01').getTime()
            if (timeA < timeB) {
              const temp = mappedOrders[i]
              mappedOrders[i] = mappedOrders[j]
              mappedOrders[j] = temp
            }
          }
        }
        
        this.allOrders = mappedOrders
        
        const recentList: Array<OrderItemType> = []
        const limit = mappedOrders.length < 5 ? mappedOrders.length : 5
        for (let i: number = 0; i < limit; i++) {
          recentList.push(mappedOrders[i])
        }
        this.recentOrders = recentList
        
        let total = 0
        let pending = 0
        let toship = 0
        let shipped = 0
        let review = 0
        
        for (let i: number = 0; i < mappedOrders.length; i++) {
          total++
          const status = mappedOrders[i].status
          if (status === 1) pending++
          else if (status === 2) toship++
          else if (status === 3) shipped++
          else if (status === 4) review++
        }
        
        this.orderCounts = {
          total: total,
          pending: pending,
          toship: toship,
          shipped: shipped,
          review: review
        }

        if (shipped > 0) {
          this.pendingReceiptGoods = {
            image: '/static/consumer/receipt.png',
            statusText: '商品运输中',
            name: '您有 ' + shipped + ' 件商品正在配送，请注意查收'
          } as PendingReceiptGoodsType
        } else {
          this.pendingReceiptGoods = null
        }
      } catch (e) {
          console.error('加载订单异常', e)
      }
    },
    
    // 切换订单Tab
    switchOrderTab(tab: string) {
      this.currentOrderTab = tab
    },

    formatOrderBadgeCount(count: number): string {
      if (count <= 0) {
        return ''
      }
      if (count > 99) {
        return '99+'
      }
      return count.toString()
    },

    openOrderAction(tab: string, type: string) {
      this.switchOrderTab(tab)
      this.goToOrders(type)
    },
    
    // 获取当前订单部分标题
    getOrderSectionTitle(): string {
      if (this.currentOrderTab === 'all') return '全部订单'
      if (this.currentOrderTab === 'pending') return '待支付订单'
      if (this.currentOrderTab === 'toship') return '待发货订单'
      if (this.currentOrderTab === 'shipped') return '待收货订单'
      if (this.currentOrderTab === 'review') return '待评价订单'
      return '我的订单'
    },

    initPage() {
      const systemInfo = uni.getSystemInfoSync()
      this.statusBarHeight = systemInfo.statusBarHeight ?? 0
      this.pageWindowHeight = systemInfo.windowHeight ?? systemInfo.screenHeight ?? 0
      this.recommendViewportHeight = this.pageWindowHeight
      // #ifdef APP-ANDROID
      this.isAndroidApp = true
      // #endif
      
      // 获取小程序胶囊按钮信息
      // #ifdef MP-WEIXIN
      try {
        const menuButton = uni.getMenuButtonBoundingClientRect()
        if (menuButton != null && menuButton.width > 0) {
          this.capsuleTop = menuButton.top
          this.capsuleBottom = menuButton.bottom
          this.capsuleLeft = menuButton.left
          this.capsuleRight = menuButton.right
          this.capsuleWidth = menuButton.width
          this.capsuleHeight = menuButton.height
          this.capsuleRightGap = systemInfo.screenWidth - menuButton.right
          this.topActionsTop = menuButton.bottom + 6
          this.topActionsRight = this.capsuleRightGap
          this.topActionsWidth = 104
          this.userHeaderRightReserve = this.topActionsWidth + 12
          this.userHeaderTopOffset = 15
          this.navBarRight = systemInfo.screenWidth - menuButton.left + 10
          console.log('[profile胶囊]', {
            screenWidth: systemInfo.screenWidth,
            capsuleTop: this.capsuleTop,
            capsuleBottom: this.capsuleBottom,
            capsuleLeft: this.capsuleLeft,
            capsuleRight: this.capsuleRight,
            topActionsTop: this.topActionsTop,
            topActionsRight: this.topActionsRight
          })
        } else {
          this.topActionsTop = this.statusBarHeight + 44
          this.topActionsRight = 16
          this.topActionsWidth = 104
          this.userHeaderRightReserve = 116
          this.userHeaderTopOffset = 8
          this.navBarRight = 96
        }
      } catch (e) {
        console.log('获取胶囊按钮信息失败', e)
        this.topActionsTop = this.statusBarHeight + 44
        this.topActionsRight = 16
        this.topActionsWidth = 104
        this.userHeaderRightReserve = 116
        this.userHeaderTopOffset = 8
        this.navBarRight = 96
      }
      // #endif
      
      // #ifndef MP-WEIXIN
      this.topActionsTop = this.statusBarHeight + 12
      this.topActionsRight = 16
      this.topActionsWidth = 104
      this.userHeaderRightReserve = 116
      this.userHeaderTopOffset = 6
      this.navBarRight = 16
      // #endif
    },
    normalizeImageUrl(url: string): string {
      if (url == null || url === '') return '/static/images/default.png'
      const trimmed = url.trim()
      if (trimmed === '') return '/static/images/default.png'
      if (trimmed.indexOf('blob:') === 0) return '/static/images/default.png'
      return trimmed
    },
    getProfilePageStyle(): string {
      if (!this.isAndroidApp) {
        return ''
      }
      if (this.pageWindowHeight <= 0) {
        return ''
      }
      return 'height:' + this.pageWindowHeight + 'px;min-height:' + this.pageWindowHeight + 'px;'
    },
    getProfileScrollStyle(): string {
      if (!this.isAndroidApp) {
        return ''
      }
      if (this.pageWindowHeight <= 0) {
        return ''
      }
      return 'height:' + this.pageWindowHeight + 'px;min-height:' + this.pageWindowHeight + 'px;'
    },
    async loadUserProfile() {
      this.refreshLoginState()
      const userId = supabaseService.getCurrentUserId()
      if (userId == null || userId === '') {
        this.resetGuestProfileState()
        return
      }

      try {
        // 获取用户资料
        const profile = await supabaseService.getUserProfile()
        if (profile != null) {
          // 映射字段
          let uId = ''
          let uPhone = ''
          let uEmail = ''
          let uNickname = ''
          let uAvatar = ''
          let uGender = 0
          
          if (profile instanceof UTSJSONObject) {
              uId = profile.getString('user_id') ?? ''
              uPhone = profile.getString('phone') ?? ''
              uEmail = profile.getString('email') ?? ''
              uNickname = profile.getString('nickname') ?? ''
              uAvatar = profile.getString('avatar_url') ?? ''
              uGender = profile.getNumber('gender') ?? 0
          } else {
              // 必须使用 JSON.parse(JSON.stringify()) 转换为 UTSJSONObject
              const profileObj = JSON.parse(JSON.stringify(profile)) as UTSJSONObject
              uId = profileObj.getString('user_id') ?? ''
              uPhone = profileObj.getString('phone') ?? ''
              uEmail = profileObj.getString('email') ?? ''
              uNickname = profileObj.getString('nickname') ?? ''
              uAvatar = profileObj.getString('avatar_url') ?? ''
              uGender = profileObj.getNumber('gender') ?? 0
          }
          
          if (uNickname === '' && uPhone !== '') {
             uNickname = uPhone.substring(0, 3) + '****' + uPhone.substring(7)
          }

           const safeAvatar = this.normalizeImageUrl(uAvatar)

           this.userInfo = {
             id: uId,
             phone: uPhone,
             email: uEmail,
             nickname: uNickname != '' ? uNickname : '微信用户',
             avatar_url: safeAvatar,
             gender: uGender,
             user_type: 1,
             status: 1,
             created_at: new Date().toISOString()
          } as UserType
        } else {
            this.resetGuestProfileState()
            this.userInfo.id = userId
            this.userInfo.nickname = '用户' + userId.substring(0, 4)
        }

        // 获取积分和余额（顺序获取，UTS不支持Promise.all数组解构）
        const balanceResult = await supabaseService.getUserBalance()
        const points = await supabaseService.getUserPoints()

        const balanceValue = balanceResult.getNumber('balance') ?? 0

        this.userStats = {
          points: points,
          balance: balanceValue,
          level: this.calculateLevel(points) // 根据积分计算等级
        } as UserStatsType

      } catch (e) {
        console.error('加载用户信息失败', e)
        // 保持默认或显示错误
      }
    },
    
    calculateLevel(points: number): number {
        if (points < 1000) return 0
        if (points < 5000) return 1
        if (points < 20000) return 2
        if (points < 50000) return 3
        return 4
    },
    
    loadConsumptionStats() {
      if (this.activeStatsPeriod === 'month') {
        this.currentStats = {
          total_amount: 1280.50,
          order_count: 8,
          avg_amount: 160.06,
          save_amount: 85.20
        } as ConsumptionStatsType
      } else if (this.activeStatsPeriod === 'quarter') {
        this.currentStats = {
          total_amount: 3680.80,
          order_count: 18,
          avg_amount: 204.49,
          save_amount: 256.30
        } as ConsumptionStatsType
      } else if (this.activeStatsPeriod === 'year') {
        this.currentStats = {
          total_amount: 15680.90,
          order_count: 56,
          avg_amount: 280.02,
          save_amount: 986.50
        } as ConsumptionStatsType
      } else {
        this.currentStats = {
          total_amount: 25680.50,
          order_count: 89,
          avg_amount: 288.55,
          save_amount: 1580.20
        } as ConsumptionStatsType
      }
    },
    
    refreshData() {
      this.refreshLoginState()
      const userId = supabaseService.getCurrentUserId()
      if (userId == null || userId === '') {
        this.resetGuestProfileState()
        return
      }

      // 刷新页面数据
      this.loadUserProfile()
      this.loadOrders()
      this.updateCouponCount() // 更新优惠券数量
    },
    
    async updateCouponCount() {
      const userId = supabaseService.getCurrentUserId()
      if (userId == null || userId === '') {
        this.serviceCounts.coupons = 0
        return
      }

      // 从 Supabase 获取真实的优惠券数量
      try {
        const count = await supabaseService.getUserCouponCount()
        this.serviceCounts.coupons = count
      } catch (e) {
        console.error('获取优惠券数量失败', e)
        this.serviceCounts.coupons = 0
      }
    },
    
    getUserLevel(): string {
      const levels = ['新手', '铜牌会员', '银牌会员', '金牌会员', '钻石会员']
      if (this.userStats.level >= 0 && this.userStats.level < levels.length) {
          return levels[this.userStats.level]
      }
      return '新手'
    },
    
    getOrderStatusText(status: number): string {
      if (status === 6) return '退款中'
      if (status === 7) return '已退款'
      const statusTexts = ['异常', '待支付', '待发货', '待收货', '已完成', '已取消']
      if (status >= 0 && status < statusTexts.length) {
          return statusTexts[status]
      }
      return '未知'
    },
    
    getOrderStatusClass(status: number): string {
      if (status === 6) return 'refunding'
      if (status === 7) return 'refunded'
      const statusClasses = ['error', 'pending', 'processing', 'shipping', 'completed', 'cancelled']
      if (status >= 0 && status < statusClasses.length) {
          return statusClasses[status]
      }
      return 'error'
    },
    
    showOrderMenu(order: OrderItemType) {
      const status = order.status
      let actions: string[] = []
      
      if (status === 1) {
        actions = ['取消订单', '联系卖家']
      } else if (status === 2) {
        actions = ['提醒发货', '申请退款', '联系卖家']
      } else if (status === 3) {
        actions = ['查看物流', '确认收货', '申请退款', '联系卖家']
      } else if (status === 4) {
        actions = ['申请售后', '再次购买', '联系卖家']
      } else if (status === 5) {
        actions = ['删除订单', '再次购买', '联系卖家']
      } else if (status === 6) {
        actions = ['退款进度', '联系卖家']
      } else if (status === 7) {
        actions = ['再次购买', '联系卖家']
      }
      
      uni.showActionSheet({
        itemList: actions,
        success: (res: ShowActionSheetSuccess) => {
          const action = actions[res.tapIndex]
          this.handleOrderAction(order, action)
        }
      })
    },
    
    handleOrderAction(order: OrderItemType, action: string) {
      if (action === '取消订单') {
        this.cancelOrderAction(order)
      } else if (action === '联系卖家') {
        this.contactSeller(order)
      } else if (action === '提醒发货') {
        this.remindShipping(order)
      } else if (action === '申请退款' || action === '申请售后') {
        this.applyRefund(order)
      } else if (action === '查看物流') {
        this.viewLogistics(order.id)
      } else if (action === '确认收货') {
        this.confirmReceive(order)
      } else if (action === '再次购买') {
        this.repurchase(order)
      } else if (action === '删除订单') {
        this.deleteOrder(order.id)
      } else if (action === '退款进度') {
        this.viewRefundProgress(order.id)
      }
    },
    
    cancelOrderAction(order: OrderItemType) {
      uni.showModal({
        title: '确认取消',
        content: '确定要取消此订单吗？',
      success: (res) => {
          if (res.confirm) {
            uni.showLoading({ title: '取消中...' })
            supabaseService.cancelOrder(order.id).then(() => {
              uni.hideLoading()
              uni.showToast({ title: '订单已取消', icon: 'success' })
              this.loadOrders()
            }).catch(() => {
              uni.hideLoading()
              uni.showToast({ title: '取消失败', icon: 'none' })
            })
          }
        }
      })
    },
    
    contactSeller(order: OrderItemType) {
      const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
      if (merchantId !== '') {
        uni.navigateTo({
          url: `/pages/mall/consumer/chat?merchantId=${merchantId}`
        })
      } else {
        uni.showToast({ title: '暂无卖家联系方式', icon: 'none' })
      }
    },
    
    getMerchantIdFromOrder(order: OrderItemType): string {
      const shopsRaw = order.ml_shops
      if (shopsRaw != null) {
        const shopStr = JSON.stringify(shopsRaw)
        const shopParsed = JSON.parse(shopStr)
        if (shopParsed != null) {
          const shopObj = shopParsed as UTSJSONObject
          return shopObj.getString('merchant_id') ?? ''
        }
      }
      return ''
    },
    
    remindShipping(order: OrderItemType) {
      uni.showLoading({ title: '提醒中...' })
      const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
      if (merchantId !== '') {
        const message = `你好，我的订单[${order.order_no}]还没有发货，请尽快安排，谢谢。`
        supabaseService.sendChatMessage(message, merchantId).then(() => {
          uni.hideLoading()
          uni.showToast({ title: '已提醒卖家发货', icon: 'success' })
        }).catch(() => {
          uni.hideLoading()
          uni.showToast({ title: '提醒失败', icon: 'none' })
        })
      } else {
        uni.hideLoading()
        uni.showToast({ title: '无法联系卖家', icon: 'none' })
      }
    },
    
    applyRefund(order: OrderItemType) {
      if (!this.ensureUserLoggedIn(`/pages/mall/consumer/apply-refund?orderId=${order.id}`)) {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/apply-refund?orderId=${order.id}`
      })
    },
    
    viewLogistics(orderId: string) {
      uni.navigateTo({
        url: `/pages/mall/consumer/logistics?orderId=${orderId}`
      })
    },
    
    repurchase(order: OrderItemType) {
      if (!this.ensureUserLoggedIn('/pages/main/profile')) {
        return
      }
      uni.showLoading({ title: '处理中...' })
      const itemsRaw = order.ml_order_items
      if (itemsRaw == null || (itemsRaw as any[]).length === 0) {
        uni.hideLoading()
        uni.showToast({ title: '订单无商品', icon: 'none' })
        return
      }
      
      const items = itemsRaw as any[]
      let completed = 0
      const total = items.length
      let successCount = 0
      
      for (let i = 0; i < items.length; i++) {
        const itemStr = JSON.stringify(items[i])
        const itemParsed = JSON.parse(itemStr)
        if (itemParsed == null) {
          completed++
          if (completed === total) {
            uni.hideLoading()
            if (successCount > 0) {
              uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
            } else {
              uni.showToast({ title: '添加失败', icon: 'none' })
            }
          }
          continue
        }
        
        const itemObj = itemParsed as UTSJSONObject
        const productId = itemObj.getString('product_id') ?? ''
        const merchantId = order.ml_shops != null ? this.getMerchantIdFromOrder(order) : ''
        
        if (productId !== '') {
          supabaseService.addToCart(productId, 1, '', merchantId).then((success) => {
            completed++
            if (success) successCount++
            if (completed === total) {
              uni.hideLoading()
              if (successCount > 0) {
                uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
              } else {
                uni.showToast({ title: '添加失败', icon: 'none' })
              }
            }
          }).catch(() => {
            completed++
            if (completed === total) {
              uni.hideLoading()
              if (successCount > 0) {
                uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
              } else {
                uni.showToast({ title: '添加失败', icon: 'none' })
              }
            }
          })
        } else {
          completed++
          if (completed === total) {
            uni.hideLoading()
            if (successCount > 0) {
              uni.showToast({ title: `已添加${successCount}件商品`, icon: 'success' })
            } else {
              uni.showToast({ title: '添加失败', icon: 'none' })
            }
          }
        }
      }
    },
    
    deleteOrder(orderId: string) {
      uni.showModal({
        title: '删除订单',
        content: '确定要删除此订单吗？',
      success: (res) => {
          if (res.confirm) {
            uni.showLoading({ title: '删除中...' })
            supabaseService.deleteOrder(orderId).then(() => {
              uni.hideLoading()
              uni.showToast({ title: '订单已删除', icon: 'success' })
              this.loadOrders()
            }).catch(() => {
              uni.hideLoading()
              uni.showToast({ title: '删除失败', icon: 'none' })
            })
          }
        }
      })
    },
    
    viewRefundProgress(orderId: string) {
      uni.navigateTo({
        url: `/pages/mall/consumer/refund?orderId=${orderId}`
      })
    },
    
    getOrderShopName(order: OrderItemType): string {
        const shopsRaw = order.ml_shops
        if (shopsRaw != null) {
            const shopStr = JSON.stringify(shopsRaw)
            const shopParsed = JSON.parse(shopStr)
            if (shopParsed != null) {
                const shopObj = shopParsed as UTSJSONObject
                const name = shopObj.getString('shop_name')
                if (name != null && name !== '') return name
            }
        }
        return '自营店铺'
    },
    
    getOrderMainImage(order: OrderItemType): string {
      const itemsRaw = order.ml_order_items
      if (itemsRaw == null) return '/static/images/default.png'
      const items = itemsRaw as any[]
      if (items.length > 0) {
          const firstItem = items[0]
          const itemStr = JSON.stringify(firstItem)
          const itemParsed = JSON.parse(itemStr)
          if (itemParsed == null) return '/static/images/default.png'
          const itemObj = itemParsed as UTSJSONObject
          const imgUrl = itemObj.getString('image_url')
          const prodImg = itemObj.getString('product_image')
          const img = (imgUrl != null && imgUrl !== '') ? imgUrl : prodImg
          if (img != null && img !== '') return img
      }
      return '/static/images/default.png'
    },
    
    getOrderTitle(order: OrderItemType): string {
      const itemsRaw = order.ml_order_items
      if (itemsRaw == null) return '精选商品'
      const items = itemsRaw as any[]
      if (items.length > 0) {
          const firstItem = items[0]
          const itemStr = JSON.stringify(firstItem)
          const itemParsed = JSON.parse(itemStr)
          if (itemParsed == null) return '精选商品'
          const itemObj = itemParsed as UTSJSONObject
          const pName = itemObj.getString('product_name')
          const name = (pName != null && pName !== '') ? pName : '商品'
          
          return name
      }
      return '精选商品'
    },
    
    getOrderSpec(order: OrderItemType): string {
      const itemsRaw = order.ml_order_items
      if (itemsRaw == null) return ''
      const items = itemsRaw as any[]
      if (items.length > 0) {
          const firstItem = items[0]
          const itemStr = JSON.stringify(firstItem)
          const itemParsed = JSON.parse(itemStr)
          if (itemParsed == null) return ''
          const itemObj = itemParsed as UTSJSONObject
          const specRaw = itemObj.get('specifications')
          if (specRaw == null) return ''
          
          if (typeof specRaw === 'string') {
              const specStr = specRaw as string
              if (specStr.startsWith('{')) {
                  try {
                      const specObj = JSON.parse(specStr) as UTSJSONObject
                      const parts: string[] = []
                      const color = specObj.get('Color')
                      if (color != null) parts.push('颜色: ' + color)
                      const size = specObj.get('Size')
                      if (size != null) parts.push('尺码: ' + size)
                      
                      if (parts.length > 0) return parts.join(' ')
                      return specStr.replace(/[{}"]/g, '')
                  } catch (e) {
                      return specStr
                  }
              }
              return specStr
          }
          return JSON.stringify(specRaw).replace(/[{}"]/g, '')
      }
      return ''
    },

    getOrderItemCount(order: OrderItemType): number {
        if (order.items_count != null && order.items_count > 0) {
            return order.items_count
        }
        return 1
    },

    formatDateTime(timeStr: string): string {
      if (timeStr == null || timeStr === '') return ''
      const date = new Date(timeStr)
      const y = date.getFullYear()
      const m = (date.getMonth() + 1).toString().padStart(2, '0')
      const d = date.getDate().toString().padStart(2, '0')
      const h = date.getHours().toString().padStart(2, '0')
      const i = date.getMinutes().toString().padStart(2, '0')
      return `${y}-${m}-${d} ${h}:${i}`
    },

    formatTime(timeStr: string): string {
      const date = new Date(timeStr)
      const now = new Date()
      const diff = now.getTime() - date.getTime()
      const days = Math.floor(diff / (1000 * 60 * 60 * 24))
      
      if (days === 0) {
        return '今天'
      } else if (days === 1) {
        return '昨天'
      } else {
        return `${days}天前`
      }
    },

    ensureUserLoggedIn(redirectUrl: string): boolean {
      const userId = supabaseService.getCurrentUserId()
      if (userId == null || userId === '') {
        goToLogin(redirectUrl)
        return false
      }
      return true
    },
    
    switchStatsPeriod(period: string) {
      this.activeStatsPeriod = period
      this.loadConsumptionStats()
    },
    
    editProfile() {
        const userId = supabaseService.getCurrentUserId()
        if (userId == null || userId === '') {
          this.goProfileLogin()
          return
        }
      uni.navigateTo({
        url: '/pages/user/profile'
      })
    },

    goProfileLogin() {
      goToLogin('/pages/main/profile')
    },
    
    // 跳转设置
    goToSettings() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/settings')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/settings'
      })
    },
    
    // 跳转钱包
    goToWallet() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/wallet')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/wallet'
      })
    },

    goToRecommendProduct(item: RecommendProductType) {
      if (item.id == null || item.id === '') {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/product-detail?id=${item.id}`
      })
    },
    
    goToOrders(type: string) {
      if (!this.ensureUserLoggedIn(`/pages/mall/consumer/orders?type=${type}`)) {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/orders?type=${type}`
      })
    },
    
    viewOrderDetail(order: OrderItemType) {
      if (!this.ensureUserLoggedIn(`/pages/mall/consumer/order-detail?orderId=${order.id}`)) {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/order-detail?orderId=${order.id}`
      })
    },
    
    goToProductFromOrder(order: OrderItemType) {
      const itemsRaw = order.ml_order_items
      if (itemsRaw == null) return
      const items = itemsRaw as any[]
      if (items.length > 0) {
        const firstItem = items[0]
        const itemStr = JSON.stringify(firstItem)
        const itemParsed = JSON.parse(itemStr)
        if (itemParsed == null) return
        const itemObj = itemParsed as UTSJSONObject
        const productId = itemObj.getString('product_id')
        if (productId != null && productId !== '') {
          uni.navigateTo({
            url: `/pages/mall/consumer/product-detail?id=${productId}`
          })
        }
      }
    },
    
    payOrder(order: OrderItemType) {
        const paymentAmount = order.actual_amount
        const userId = supabaseService.getCurrentUserId()
        if (userId == null || userId === '') {
          goToLogin(`/pages/mall/consumer/payment?orderId=${order.id}&amount=${paymentAmount}`)
          return
        }
      uni.navigateTo({
        url: `/pages/mall/consumer/payment?orderId=${order.id}&amount=${paymentAmount}`
      })
    },
    
    confirmReceive(order: OrderItemType) {
      uni.showModal({
        title: '确认收货',
        content: '确认已收到商品吗？',
      success: (res) => {
          if (res.confirm) {
            uni.showLoading({ title: '处理中...' })
            supabaseService.confirmOrderReceived(order.id).then(() => {
              uni.hideLoading()
              uni.showToast({
                title: '确认收货成功',
                icon: 'success'
              })
              this.loadOrders()
            }).catch(() => {
              uni.hideLoading()
              uni.showToast({
                title: '操作失败',
                icon: 'none'
              })
            })
          }
        }
      })
    },
    
    reviewOrder(order: OrderItemType) {
      if (!this.ensureUserLoggedIn(`/pages/mall/consumer/review?orderId=${order.id}`)) {
        return
      }
      uni.navigateTo({
        url: `/pages/mall/consumer/review?orderId=${order.id}`
      })
    },
    
    goToCoupons() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/coupons')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/coupons'
      })
    },
    
    goToMessages() {
      if (!this.ensureUserLoggedIn('/pages/main/messages')) {
        return
      }
      uni.switchTab({
        url: '/pages/main/messages'
      })
    },

    goToPoints() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/points/index')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/points/index'
      })
    },
    
    goToAddress() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/address-list')) {
        return
      }
      // 暂时跳转到设置页的地址管理
      uni.navigateTo({
        url: '/pages/mall/consumer/address-list'
      })
    },
    
    goToFavorites() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/favorites')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/favorites'
      })
    },
    
    goToFootprint() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/footprint')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/footprint'
      })
    },
    
    goToRefund() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/orders?type=refund')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/orders?type=refund'
      })
    },
    
    contactService() {
      if (!this.ensureUserLoggedIn('/pages/mall/service/chat')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/service/chat'
      })
    },
    goToOrderReviews() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/orders?type=review')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/orders?type=review'
      })
    },
    goToMySubscriptions() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/subscription/my-subscriptions')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/subscription/my-subscriptions'
      })
    },
    goToFollowedShops() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/subscription/followed-shops')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/subscription/followed-shops'
      })
    },
    goToBalance() {
      if (!this.ensureUserLoggedIn('/pages/mall/consumer/balance/index')) {
        return
      }
      uni.navigateTo({
        url: '/pages/mall/consumer/balance/index'
      })
    },
    
    goToShare() {
      uni.navigateTo({
        url: '/pages/mall/consumer/share/index'
      })
    },
    
    goToMember() {
      uni.navigateTo({
        url: '/pages/mall/consumer/member/index'
      })
    },
    
    changePassword() {
      uni.navigateTo({
        url: '/pages/mall/consumer/change-password'
      })
    },
    
    bindPhone() {
      uni.navigateTo({
        url: '/pages/mall/consumer/bind-phone'
      })
    },
    
    bindEmail() {
      uni.navigateTo({
        url: '/pages/mall/consumer/bind-email'
      })
    },
    
    handleOrderUpdated(data: any) {
      console.log('收到订单更新事件:', data)
      this.refreshData()
      
      const dataObj = data as UTSJSONObject
      const status = dataObj.getNumber('status')
      if (status === 1) {
        uni.showToast({
          title: '订单已保存到待支付',
          icon: 'success'
        })
      } else if (status === 2) {
        uni.showToast({
          title: '支付成功，订单待发货',
          icon: 'success'
        })
      }
    },

    handleAuthChanged(data: any) {
      this.refreshLoginState()
      let payload: UTSJSONObject | null = null

      if (data instanceof UTSJSONObject) {
        payload = data as UTSJSONObject
      } else {
        try {
          const raw = JSON.stringify(data)
          if (raw !== '' && raw !== 'null') {
            payload = JSON.parse(raw) as UTSJSONObject
          }
        } catch (e) {
          console.error('[profile] authChanged payload parse failed:', e)
        }
      }

      if (payload == null) {
        return
      }

      const loggedIn = payload.getBoolean('loggedIn')
      if (loggedIn === true) {
        this.refreshData()
        return
      }

      if (loggedIn === false) {
        this.resetGuestProfileState()
      }
    }
  }
}
</script>

<style>
.consumer-profile {
  width: 100%;
  height: 100vh;
  min-height: 100vh;
  background-color: #f5f5f5;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.profile-scroll-content {
  flex: 1;
  height: 0;
  width: 100%;
  background-color: #f5f5f5;
}

.profile-page-inner {
  width: 100%;
  min-height: 100%;
  background-color: #f5f5f5;
}

.jd-profile-top {
  position: relative;
  width: 100%;
  min-height: 260px;
  padding-left: 14px;
  padding-right: 14px;
  padding-bottom: 24px;
  box-sizing: border-box;
  background-color: #ff5a36;
  background-image: linear-gradient(180deg, #ff3b30 0%, #ff5a36 60%, #f5f5f5 100%);
}

.jd-profile-top-android {
  background-image: none;
  background-color: #ff5a36;
}

.jd-user-header {
  min-height: 88px;
  display: flex;
  flex-direction: row;
  align-items: center;
  box-sizing: border-box;
}

.jd-user-brief {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.jd-user-avatar {
  width: 58px;
  height: 58px;
  border-radius: 29px;
  border-width: 2px;
  border-style: solid;
  border-color: rgba(255, 255, 255, 0.9);
  background-color: #eeeeee;
  flex-shrink: 0;
  margin-right: 10px;
}

.jd-user-texts {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.jd-user-name-row {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.jd-user-name {
  flex: 1;
  min-width: 0;
  max-width: none;
  font-size: 20px;
  color: #ffffff;
  font-weight: 800;
  lines: 1;
  text-overflow: ellipsis;
}

.jd-user-tag-row {
  margin-top: 6px;
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: nowrap;
  overflow: hidden;
}

.jd-user-tag {
  height: 22px;
  line-height: 22px;
  padding-left: 8px;
  padding-right: 8px;
  margin-right: 6px;
  border-radius: 11px;
  background-color: rgba(255, 255, 255, 0.22);
  color: rgba(255, 255, 255, 0.95);
  font-size: 11px;
  white-space: nowrap;
  lines: 1;
  text-overflow: ellipsis;
}

.jd-user-tag-secondary {
  flex: 1;
  min-width: 0;
  padding-left: 6px;
  padding-right: 6px;
  margin-right: 0;
  font-size: 10px;
}

.capsule-below-actions {
  position: absolute;
  z-index: 20;
  height: 48px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
}

.capsule-action-item {
  width: 48px;
  height: 46px;
  margin-left: 4px;
  border-radius: 10px;
  background-color: transparent;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.capsule-action-icon {
  width: 20px;
  height: 20px;
  margin-bottom: 2px;
}

.capsule-action-fallback {
  width: 20px;
  height: 20px;
  font-size: 13px;
  color: #ffffff;
  text-align: center;
  line-height: 20px;
  margin-bottom: 2px;
}

.capsule-action-text {
  font-size: 11px;
  color: #ffffff;
  font-weight: 500;
  line-height: 14px;
}

.jd-wallet-card {
  position: relative;
  margin-top: 2px;
  height: 150px;
  border-radius: 18px;
  background-color: #ffffff;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.wallet-plus-ribbon {
  position: absolute;
  top: 0;
  right: 0;
  width: 68%;
  height: 48px;
  border-top-right-radius: 18px;
  border-bottom-left-radius: 34px;
  background-color: #8a6638;
  background-image: linear-gradient(90deg, #5a3a21 0%, #75542f 52%, #a68049 100%);
  z-index: 2;
  overflow: hidden;
}

.wallet-plus-ribbon-android {
  background-image: none;
  background-color: #8a6638;
}



.wallet-plus-bg-decor {
  position: absolute;
  right: -18px;
  top: -24px;
  width: 72px;
  height: 72px;
  border-radius: 36px;
  background-color: rgba(255, 230, 180, 0.22);
}

.wallet-title-block {
  position: absolute;
  top: 0;
  left: 0;
  width: 42%;
  height: 56px;
  padding-left: 16px;
  border-top-left-radius: 18px;
  border-bottom-right-radius: 42px;
  background-color: #ffffff;
  z-index: 4;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.wallet-curve-cover {
  position: absolute;
  left: 25%;
  top: -24px;
  width: 82px;
  height: 94px;
  border-radius: 47px;
  background-color: #ffffff;
  z-index: 5;
}

.wallet-plus-content {
  position: absolute;
  top: 0;
  left: 49%;
  right: 8px;
  height: 48px;
  z-index: 6;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.wallet-crown-icon {
  width: 18px;
  font-size: 16px;
  color: #ffd77a;
  margin-right: 4px;
  text-align: center;
  flex-shrink: 0;
}

.wallet-plus-title {
  font-size: 13px;
  color: #fff1d0;
  font-weight: 800;
  margin-right: 4px;
  white-space: nowrap;
  flex-shrink: 0;
}

.wallet-plus-desc {
  flex: 1;
  min-width: 0;
  font-size: 10px;
  color: rgba(255, 241, 208, 0.86);
  lines: 1;
  text-overflow: ellipsis;
}

.wallet-plus-arrow {
  width: 22px;
  height: 22px;
  border-radius: 11px;
  background-color: rgba(255, 240, 210, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 5px;
  flex-shrink: 0;
}

.wallet-plus-arrow-text {
  font-size: 18px;
  color: #7a5730;
  line-height: 22px;
}

.wallet-title-text {
  font-size: 17px;
  color: #222222;
  font-weight: 800;
}

.wallet-title-arrow {
  margin-left: 5px;
  font-size: 18px;
  color: #222222;
  font-weight: 700;
}

.wallet-assets-row {
  position: relative;
  z-index: 6;
  margin-top: 62px;
  padding-left: 8px;
  padding-right: 48px;
  height: 70px;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.wallet-asset-item {
  flex: 1;
  min-width: 0;
  height: 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.wallet-asset-value {
  font-size: 19px;
  color: #111111;
  font-weight: 800;
  lines: 1;
  text-overflow: ellipsis;
}

.wallet-asset-label {
  margin-top: 4px;
  font-size: 12px;
  color: #666666;
  lines: 1;
  text-overflow: ellipsis;
}

.wallet-more-entry {
  position: absolute;
  right: 8px;
  top: 64px;
  width: 36px;
  height: 70px;
  border-left-width: 1px;
  border-left-style: solid;
  border-left-color: #eeeeee;
  z-index: 7;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.wallet-more-text {
  font-size: 12px;
  color: #333333;
  line-height: 16px;
  text-align: center;
}

.wallet-more-circle {
  margin-top: 5px;
  width: 23px;
  height: 23px;
  border-radius: 12px;
  border-width: 1px;
  border-style: solid;
  border-color: #666666;
  display: flex;
  align-items: center;
  justify-content: center;
}

.wallet-more-arrow {
  font-size: 18px;
  color: #333333;
  line-height: 22px;
}

.jd-section-card {
  margin: 12px 14px 0 14px;
  padding: 16px;
  border-radius: 16px;
  background-color: #ffffff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
}

.order-card {
  margin: 12px 14px 0 14px;
  padding: 14px 16px 14px;
  border-radius: 18px;
  background-color: #ffffff;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.04);
}

.card-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.card-title {
  font-size: 17px;
  font-weight: 700;
  color: #222222;
}

.card-subtitle {
  margin-top: 6px;
  display: block;
  font-size: 12px;
  color: #8b90a0;
}

.card-link {
  font-size: 13px;
  color: #999999;
}

.order-header {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.order-title {
  font-size: 17px;
  font-weight: 700;
  color: #222222;
}

.order-all-link {
  display: flex;
  flex-direction: row;
  align-items: center;
  color: #999999;
}

.order-all-arrow {
  margin-left: 4px;
  font-size: 15px;
  color: #bbbbbb;
  line-height: 15px;
}

.order-actions {
  margin-top: 14px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-start;
  overflow: visible;
}

.order-action {
  width: 25%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  overflow: visible;
}

.order-action.active .order-action-text {
  color: #222222;
  font-weight: 600;
}

.order-icon-wrap {
  position: relative;
  width: 40px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: transparent;
  border-radius: 0;
  overflow: visible;
}

.order-icon-img {
  width: 32px;
  height: 32px;
  display: block;
}

.order-badge {
  position: absolute;
  top: -3px;
  right: -5px;
  z-index: 5;
  min-width: 14px;
  height: 14px;
  padding-left: 3px;
  padding-right: 3px;
  border-radius: 999px;
  background-color: #ff3b30;
  border-width: 1px;
  border-style: solid;
  border-color: #ffffff;
  color: #ffffff;
  font-size: 9px;
  font-weight: 600;
  line-height: 14px;
  text-align: center;
}

.order-action-text {
  margin-top: 8px;
  font-size: 12px;
  color: #444444;
  line-height: 16px;
  text-align: center;
}

.pending-receipt-strip {
  margin-top: 14px;
  min-height: 50px;
  padding: 8px 10px;
  display: flex;
  flex-direction: row;
  align-items: center;
  background-color: #f7f8fa;
  border-radius: 12px;
}

.pending-goods-img {
  width: 32px;
  height: 32px;
  border-radius: 4px;
  flex-shrink: 0;
  background-color: #eeeeee;
}

.pending-goods-info {
  flex: 1;
  min-width: 0;
  margin-left: 10px;
}

.pending-goods-title-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  min-width: 0;
}

.pending-status {
  margin-right: 8px;
  font-size: 12px;
  font-weight: 600;
  color: #333333;
}

.pending-desc {
  flex: 1;
  font-size: 11px;
  color: #888888;
  lines: 1;
  text-overflow: ellipsis;
}

.pending-goods-name {
  margin-top: 3px;
  display: block;
  font-size: 11px;
  color: #666666;
  lines: 1;
  text-overflow: ellipsis;
}

.pending-arrow {
  margin-left: 10px;
  font-size: 18px;
  color: #bbbbbb;
}

.service-card {
  margin: 12px 14px 0 14px;
  padding: 14px 0 14px;
  border-radius: 18px;
  background-color: #ffffff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.04);
  overflow: hidden;
}

.service-header {
  padding-left: 16px;
  padding-right: 16px;
  margin-bottom: 14px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.service-title {
  font-size: 17px;
  font-weight: 700;
  color: #222222;
}

.service-scroll {
  width: 100%;
  box-sizing: border-box;
  white-space: nowrap;
}

.service-row {
  display: inline-flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: flex-start;
  padding-left: 12px;
  padding-right: 18px;
}

.service-item {
  width: 64px;
  flex: 0 0 64px;
  flex-shrink: 0;
  margin-right: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
}

.service-icon-wrap {
  width: 28px;
  height: 28px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  position: relative;
  background-color: transparent;
  border-radius: 0;
  overflow: visible;
}

.service-icon-img {
  width: 26px;
  height: 26px;
  display: block;
}

.service-text-icon {
  font-size: 16px;
  font-weight: 600;
  color: #999999;
  line-height: 28px;
}

.service-badge {
  min-width: 14px;
  height: 14px;
  padding-left: 3px;
  padding-right: 3px;
  border-radius: 7px;
  background-color: #ff3d2b;
  color: #ffffff;
  font-size: 9px;
  font-weight: 700;
  text-align: center;
  line-height: 14px;
  position: absolute;
  top: -6px;
  right: -8px;
}

.service-name {
  margin-top: 6px;
  font-size: 11px;
  color: #333333;
  line-height: 14px;
  text-align: center;
  white-space: nowrap;
}

.service-row-end-spacer {
  width: 18px;
  height: 1px;
  flex-shrink: 0;
}

.recommend-section {
  margin: 16px 16px 0 16px;
}

.recommend-header {
  padding-left: 4px;
  padding-right: 4px;
  margin-bottom: 12px;
}

.recommend-title {
  font-size: 18px;
  font-weight: 700;
  color: #222222;
}

.recommend-subtitle {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: #8b90a0;
}

.recommend-grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.recommend-card {
  width: 48.2%;
  margin-bottom: 12px;
  border-radius: 18px;
  background-color: #ffffff;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(32, 35, 66, 0.07);
}

.recommend-image {
  width: 100%;
  height: 132px;
  background-color: #f0f1f5;
}

.recommend-info {
  padding: 12px;
}

.recommend-name {
  font-size: 13px;
  color: #222222;
  line-height: 20px;
  lines: 2;
  text-overflow: ellipsis;
}

.recommend-meta-row {
  margin-top: 10px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.recommend-price {
  font-size: 16px;
  color: #ff4d31;
  font-weight: 700;
}

.recommend-tag {
  padding-left: 8px;
  padding-right: 8px;
  height: 22px;
  border-radius: 11px;
  background-color: #fff0eb;
  color: #ff5a3a;
  font-size: 11px;
  line-height: 22px;
}

.recommend-load-more {
  width: 100%;
  height: 48px;
  display: flex;
  align-items: center;
  flex-direction: row;
  justify-content: center;
}

.recommend-load-text {
  font-size: 13px;
  color: #999999;
}

.profile-bottom-safe {
  height: 156px;
}

.guest-login-bar {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(var(--window-bottom) + 12px);
  height: 48px;
  padding: 0 8px 0 10px;
  border-radius: 24px;
  background-color: rgba(45, 38, 42, 0.72);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  backdrop-filter: blur(10px);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  z-index: 998;
}

.guest-login-left {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
}

.guest-login-avatar {
  width: 32px;
  height: 32px;
  border-radius: 16px;
  margin-right: 8px;
  background-color: rgba(255, 255, 255, 0.85);
}

.guest-login-text {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: #ffffff;
  lines: 1;
}

.guest-login-btn {
  height: 32px;
  line-height: 32px;
  padding: 0 14px;
  border-radius: 16px;
  background-color: #ff6a4d;
  color: #ffffff;
  font-size: 12px;
  font-weight: 600;
  margin-left: 8px;
}

.guest-login-btn::after {
  border: none;
}

.pending {
  color: #ff4d31;
}

.processing {
  color: #ff8b2b;
}

.shipping {
  color: #3f7cff;
}

.completed {
  color: #16a34a;
}

.refunding {
  color: #ff8b2b;
}

.refunded,
.cancelled,
.error {
  color: #9aa0af;
}

@media screen and (max-width: 375px) {
  .capsule-below-actions {
    width: 96px !important;
  }

  .jd-wallet-card {
    height: 144px;
  }

  .wallet-plus-ribbon {
    width: 67%;
  }

  .wallet-title-block {
    width: 41%;
    padding-left: 12px;
  }

  .wallet-curve-cover {
    left: 36%;
    top: -24px;
    width: 76px;
    height: 88px;
    border-radius: 44px;
  }

  .wallet-plus-content {
    left: 49%;
    right: 8px;
  }

  .wallet-title-text {
    font-size: 15px;
  }

  .wallet-crown-icon {
    width: 16px;
    font-size: 15px;
    margin-right: 3px;
  }

  .wallet-plus-title {
    font-size: 12px;
    margin-right: 3px;
  }

  .wallet-plus-desc {
    font-size: 9px;
  }

  .wallet-assets-row {
    margin-top: 60px;
    padding-left: 4px;
    padding-right: 44px;
  }

  .wallet-asset-value {
    font-size: 17px;
  }

  .wallet-asset-label {
    font-size: 11px;
  }

  .capsule-action-item {
    width: 46px;
    height: 42px;
    margin-left: 2px;
  }

  .jd-user-name {
    font-size: 19px;
  }

  .jd-user-avatar {
    width: 54px;
    height: 54px;
    border-radius: 27px;
  }

  .jd-user-tag {
    font-size: 10px;
    padding-left: 6px;
    padding-right: 6px;
    margin-right: 4px;
  }

  .jd-user-tag-secondary {
    padding-left: 4px;
    padding-right: 4px;
    font-size: 9px;
  }
}
</style>
