<template>
  <view class="user-container">
    <!-- 搜索栏 -->
    <view class="search-bar">
      <view class="search-input-wrapper">
        <AppIcon name="search" size="16" color="#999999" class="search-icon" />
        <input type="text" placeholder="搜索手机号" v-model="searchKeyword" @confirm="handleSearch" />
      </view>
      <button class="search-btn" @click="handleSearch">搜索</button>
      <button class="refund-nav-btn" @click="navigateToRefund">退款处理</button>
    </view>

    <!-- 用户列表 -->
    <view class="user-list" v-if="list.length > 0">
      <view class="user-item" v-for="(item, index) in list" :key="index">
        <view class="item-header">
          <view class="item-left">
            <view class="item-phone-row">
              <text class="item-phone">{{ item.mobilePhone || '-' }}</text>
              <AppIcon v-if="item.mobilePhone" name="copy" :size="26" color="#C6171E" class="copy-icon" @click.stop="copyText(item.mobilePhone)" />
            </view>
            <view class="item-id-row">
              <text class="item-id">UID: {{ item.userId || '-' }}</text>
              <AppIcon v-if="item.userId" name="copy" :size="26" color="#C6171E" class="copy-icon" @click.stop="copyText(item.userId)" />
            </view>
          </view>
          <view class="item-header-right">
            <text class="status-tag" :style="getStatusStyle(item.status)">{{ fmtDictName('User.status', item.status) }}</text>
            <button class="refund-btn" @click.stop="handleApplyRefund(item)">退款</button>
          </view>
        </view>
        <view class="item-content">
          <!-- 余额概览 -->
          <view class="balance-grid">
            <view class="balance-item">
              <text class="balance-label">总余额</text>
              <text class="balance-value primary">{{ formatAmount(item.balance) }}</text>
            </view>
            <view class="balance-item">
              <text class="balance-label">充值余额</text>
              <text class="balance-value">{{ formatAmount(item.rechargeBalance) }}</text>
            </view>
            <view class="balance-item">
              <text class="balance-label">赠金余额</text>
              <text class="balance-value">{{ formatAmount(item.grantsBalance) }}</text>
            </view>
            <view class="balance-item">
              <text class="balance-label">冻结余额</text>
              <text class="balance-value warn">{{ formatAmount(item.frozenAmount) }}</text>
            </view>
          </view>
          <view class="divider"></view>
          <!-- 消费概览 -->
          <view class="info-grid">
            <view class="info-item">
              <text class="info-label">归属站点</text>
              <text class="info-value">{{ item.stationName || '-' }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">注册时间</text>
              <text class="info-value">{{ formatTime(item.registerTime) }}</text>
            </view>
          </view>
          <view class="stats-row">
            <view class="stat-item">
              <text class="stat-num">{{ item.rechargeTimes || 0 }}</text>
              <text class="stat-label">充值次数</text>
            </view>
            <view class="stat-item">
              <text class="stat-num amount">{{ formatAmount(item.rechargeAmount) }}</text>
              <text class="stat-label">充值金额</text>
            </view>
            <view class="stat-item">
              <text class="stat-num">{{ item.washTimes || 0 }}</text>
              <text class="stat-label">洗车次数</text>
            </view>
            <view class="stat-item">
              <text class="stat-num amount">{{ formatAmount(item.amount) }}</text>
              <text class="stat-label">消费总额</text>
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- 加载更多 -->
    <view class="load-more" v-if="list.length > 0">
      <text class="load-more-text" v-if="loadMoreStatus === 'more'">上拉加载更多</text>
      <text class="load-more-text" v-else-if="loadMoreStatus === 'loading'">正在加载...</text>
      <text class="load-more-text" v-else>没有更多数据了</text>
    </view>

    <!-- 空状态 -->
    <view class="empty-state" v-if="list.length === 0 && !loading">
      <view class="empty-icon-wrapper"><AppIcon name="users" size="48" color="#BFBFBF" /></view>
      <text class="empty-text">暂无用户数据</text>
    </view>

    <!-- 加载状态 -->
    <view class="loading-state" v-if="loading && list.length === 0">
      <view class="loading-spinner"></view>
      <text class="loading-text">加载中...</text>
    </view>

    <!-- 退款弹窗 -->
    <view class="modal-overlay" v-if="showRefundModal" @click="closeRefundModal">
      <view class="modal-card" @click.stop>
        <text class="modal-title">申请退款</text>
        <view class="modal-content">
          <view class="modal-row">
            <text class="modal-label">用户</text>
            <text class="modal-value">{{ refundUser?.mobilePhone || '-' }}</text>
          </view>
          <view class="modal-row">
            <text class="modal-label">退款原因</text>
            <input class="modal-input" type="text" v-model="refundReason" placeholder="请输入退款原因" />
          </view>
        </view>
        <view class="modal-footer">
          <button class="modal-btn cancel" @click="closeRefundModal">取消</button>
          <button class="modal-btn confirm" @click="confirmRefund" :disabled="!refundReason.trim()">确认</button>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
import { getAppUserList } from '../../api/user.js'
import { applyRefund } from '../../api/finance.js'
import { formatTime, showToast, formatAmount, fmtDictName, getDictColor, copyText } from '../../utils/index.js'
import { loadDicts } from '../../utils/dict.js'

const list = ref([])
const loading = ref(true)
const page = ref(1)
const pageSize = ref(10)
const hasMore = ref(true)
const loadMoreStatus = ref('more')
const searchKeyword = ref('')
const showRefundModal = ref(false)
const refundUser = ref(null)
const refundReason = ref('')

const getStatusStyle = (status) => {
  const color = getDictColor('User.status', status)
  if (color) return { color, backgroundColor: `${color}1A` }
  return {}
}

const loadData = async (isLoadMore = false) => {
  if (!isLoadMore) {
    page.value = 1
    list.value = []
    hasMore.value = true
    loadMoreStatus.value = 'more'
  } else {
    loadMoreStatus.value = 'loading'
  }

  loading.value = true
  try {
    const params = {
      pageNum: page.value,
      pageSize: pageSize.value
    }
    if (searchKeyword.value) params.mobilePhone = searchKeyword.value

    const res = await getAppUserList(params)
    if (res && res.code === 200) {
      const data = res.data
      const records = data.records || data.list || data
      const total = data.total || 0

      const totalPages = Math.ceil(total / pageSize.value)
      hasMore.value = page.value < totalPages
      loadMoreStatus.value = hasMore.value ? 'more' : 'noMore'

      if (isLoadMore) {
        list.value = [...list.value, ...records]
        page.value++
      } else {
        list.value = records
        page.value = 2
      }
    }
  } catch (error) {
    console.error('加载用户列表失败:', error)
  } finally {
    loading.value = false
  }
}

const loadMore = () => {
  if (hasMore.value && !loading.value && loadMoreStatus.value !== 'loading') {
    loadData(true)
  }
}

onReachBottom(() => {
  loadMore()
})

const handleSearch = () => {
  loadData()
}

const navigateToRefund = () => {
  uni.navigateTo({ url: '/pages/finance/refund' })
}

const handleApplyRefund = (item) => {
  refundUser.value = item
  refundReason.value = ''
  showRefundModal.value = true
}

const closeRefundModal = () => {
  showRefundModal.value = false
  refundUser.value = null
  refundReason.value = ''
}

const confirmRefund = async () => {
  if (!refundReason.value.trim()) return

  try {
    const res = await applyRefund({
      userId: refundUser.value.userId,
      reason: refundReason.value.trim()
    })
    if (res && res.code === 200) {
      closeRefundModal()
      uni.showModal({
        title: '申请成功',
        content: '退款申请已提交，是否立即前往处理？',
        confirmText: '前往处理',
        cancelText: '关闭',
        success: (modalRes) => {
          if (modalRes.confirm) {
            uni.navigateTo({ url: '/pages/finance/refund' })
          }
        }
      })
    } else {
      showToast(res?.msg || '提交失败')
    }
  } catch (error) {
    console.error('申请退款失败:', error)
  }
}

onMounted(async () => {
  await loadDicts()
  loadData()
})
</script>

<style scoped>
.user-container {
  min-height: 100vh;
  background-color: #F5F7FA;
  padding-bottom: 100rpx;
}

.search-bar {
  display: flex;
  align-items: center;
  padding: 20rpx;
  background-color: #FFFFFF;
}
.search-input-wrapper {
  flex: 1;
  display: flex;
  align-items: center;
  background-color: #F5F5F5;
  border-radius: 16rpx;
  padding: 0 20rpx;
}
.search-icon { font-size: 28rpx; margin-right: 10rpx; }
.search-input-wrapper input { flex: 1; height: 64rpx; font-size: 28rpx; }
.search-btn {
  margin-left: 20rpx;
  height: 64rpx;
  line-height: 64rpx;
  padding: 0 28rpx;
  background: #C6171E;
  color: #FFFFFF;
  border-radius: 16rpx;
  font-size: 26rpx;
  border: none;
}

.search-btn:active {
  background: #A81212;
  transform: scale(0.97);
}

.refund-nav-btn {
  margin-left: 12rpx;
  height: 64rpx;
  line-height: 64rpx;
  padding: 0 20rpx;
  background: #FFFFFF;
  color: #C6171E;
  border: 2rpx solid #C6171E;
  border-radius: 16rpx;
  font-size: 24rpx;
  white-space: nowrap;
}

.refund-nav-btn:active {
  background: #FFF0F0;
  transform: scale(0.97);
}

.user-list {
  padding: 20rpx;
}
.user-item {
  background-color: #FFFFFF;
  border-radius: 20rpx;
  padding: 24rpx;
  margin-bottom: 20rpx;
  box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
}
.item-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding-bottom: 16rpx;
  border-bottom: 1rpx solid #F0F0F0;
  margin-bottom: 16rpx;
}
.item-phone-row {
  display: flex;
  align-items: center;
  gap: 8rpx;
}
.item-phone {
  font-size: 30rpx;
  font-weight: 600;
  color: #1A1A1A;
}
.item-id-row {
  display: flex;
  align-items: center;
  gap: 8rpx;
  margin-top: 4rpx;
}
.item-id {
  font-size: 22rpx;
  color: #999999;
}
.copy-icon {
  flex-shrink: 0;
}
.item-header-right {
  display: flex;
  align-items: center;
  gap: 12rpx;
  flex-shrink: 0;
}
.status-tag {
  font-size: 22rpx;
  padding: 6rpx 16rpx;
  border-radius: 20rpx;
  font-weight: 500;
}

.balance-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16rpx;
}
.balance-item {
  padding: 12rpx;
  background-color: #F5F7FA;
  border-radius: 12rpx;
}
.balance-label {
  font-size: 22rpx;
  color: #999999;
  display: block;
  margin-bottom: 4rpx;
}
.balance-value {
  font-size: 28rpx;
  font-weight: 600;
  color: #1A1A1A;
}
.balance-value.primary {
  color: #C6171E;
}
.balance-value.warn {
  color: #C6171E;
}

.divider {
  height: 1rpx;
  background-color: #F0F0F0;
  margin: 16rpx 0;
}

.info-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12rpx;
}
.info-item {
  padding: 4rpx 0;
}
.info-label {
  font-size: 24rpx;
  color: #999999;
  display: block;
  margin-bottom: 4rpx;
}
.info-value {
  font-size: 26rpx;
  color: #1A1A1A;
}

.stats-row {
  display: flex;
  justify-content: space-between;
  padding: 16rpx 0 8rpx;
  border-top: 1rpx solid #F0F0F0;
  margin-top: 12rpx;
}
.stat-item {
  text-align: center;
  flex: 1;
}
.stat-num {
  font-size: 26rpx;
  font-weight: 600;
  color: #1A1A1A;
  display: block;
}
.stat-num.amount {
  font-size: 22rpx;
  color: #C6171E;
}
.stat-label {
  font-size: 20rpx;
  color: #999999;
  display: block;
  margin-top: 2rpx;
}

.refund-btn {
  padding: 6rpx 20rpx;
  background: #C6171E;
  color: #FFFFFF;
  border-radius: 16rpx;
  font-size: 22rpx;
  border: none;
  line-height: 1.4;
}

.load-more {
  display: flex;
  justify-content: center;
  padding: 30rpx 0;
}
.load-more-text { font-size: 26rpx; color: #999999; }

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 120rpx 0;
}
.empty-icon { font-size: 120rpx; margin-bottom: 20rpx; }
.empty-text { font-size: 28rpx; color: #999999; }

.loading-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 120rpx 0;
}
.loading-spinner {
  font-size: 60rpx;
  animation: spin 1s linear infinite;
}
.loading-text { font-size: 28rpx; color: #999999; margin-top: 20rpx; }

/* 退款弹窗 */
.modal-overlay {
  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: 1000;
}
.modal-card {
  width: 600rpx;
  background-color: #FFFFFF;
  border-radius: 24rpx;
  padding: 36rpx;
}
.modal-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #1A1A1A;
  display: block;
  text-align: center;
  margin-bottom: 30rpx;
}
.modal-content {
  margin-bottom: 30rpx;
}
.modal-row {
  margin-bottom: 20rpx;
}
.modal-label {
  font-size: 26rpx;
  color: #999999;
  display: block;
  margin-bottom: 10rpx;
}
.modal-value {
  font-size: 28rpx;
  color: #1A1A1A;
  font-weight: 500;
}
.modal-input {
  width: 100%;
  height: 72rpx;
  background-color: #F5F5F5;
  border-radius: 16rpx;
  padding: 0 20rpx;
  font-size: 28rpx;
  box-sizing: border-box;
}
.modal-footer {
  display: flex;
  gap: 20rpx;
}
.modal-btn {
  flex: 1;
  padding: 20rpx 0;
  border-radius: 16rpx;
  font-size: 28rpx;
  border: none;
}
.modal-btn.cancel {
  background-color: #F5F5F5;
  color: #666666;
}
.modal-btn.confirm {
  background: #C6171E;
  color: #FFFFFF;
}
.modal-btn.confirm[disabled] {
  opacity: 0.5;
}
</style>
