<script setup>
import { ref } from "vue";
import { onPullDownRefresh, onReachBottom, onShow } from "@dcloudio/uni-app";
import { getMyPoints, getMyPointRecords } from "@/api/point";
import { checkLogin } from "@/utils/auth";

onShow(() => { checkLogin(); });

const balance = ref(0);
const records = ref([]);
const page = ref(1);
const pageSize = 15;
const hasMore = ref(true);
const loading = ref(false);

const fetchBalance = async () => {
  try {
    const res = await getMyPoints();
    balance.value = res.balance ?? res.points ?? 0;
  } catch (e) {
    console.error(e);
  }
};

const fetchRecords = async (reset = false) => {
  if (loading.value) return;
  if (!reset && !hasMore.value) return;

  loading.value = true;
  if (reset) {
    page.value = 1;
    hasMore.value = true;
  }

  try {
    const res = await getMyPointRecords({ page: page.value, page_size: pageSize });
    const list = res.items || res.data || res || [];

    if (reset) {
      records.value = list;
    } else {
      records.value.push(...list);
    }

    if (list.length < pageSize) {
      hasMore.value = false;
    } else {
      page.value++;
    }
  } catch (e) {
    console.error(e);
  } finally {
    loading.value = false;
  }
};

const formatDate = (dateStr) => {
  if (!dateStr) return "";
  const d = new Date(dateStr);
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  const h = String(d.getHours()).padStart(2, "0");
  const min = String(d.getMinutes()).padStart(2, "0");
  return `${y}-${m}-${day} ${h}:${min}`;
};

const formatChange = (val) => {
  return val > 0 ? `+${val}` : `${val}`;
};

onPullDownRefresh(async () => {
  await Promise.all([fetchBalance(), fetchRecords(true)]);
  uni.stopPullDownRefresh();
});

onReachBottom(() => {
  fetchRecords();
});

fetchBalance();
fetchRecords(true);
</script>

<template>
  <view class="points-page">
    <view class="balance-card">
      <text class="balance-label">当前积分</text>
      <text class="balance-value">{{ balance }}</text>
    </view>

    <view class="section-header">
      <text class="section-title">积分记录</text>
    </view>

    <view class="records-list">
      <view
        v-for="item in records"
        :key="item.id"
        class="record-item"
      >
        <view class="record-left">
          <text class="record-reason">{{ item.reason || "积分变动" }}</text>
          <text class="record-date">{{ formatDate(item.created_at) }}</text>
        </view>
        <text
          class="record-change"
          :class="item.change > 0 ? 'positive' : 'negative'"
        >
          {{ formatChange(item.change) }}
        </text>
      </view>

      <view v-if="loading" class="status-tip">
        <text>加载中...</text>
      </view>
      <view v-else-if="!hasMore && records.length > 0" class="status-tip">
        <text>没有更多了</text>
      </view>
      <view v-else-if="!loading && records.length === 0" class="empty-state">
        <uni-icons type="star-filled" size="48" color="#6366f1" class="empty-icon" />
        <text class="empty-title">暂无积分记录</text>
        <text class="empty-desc">投稿取景地、获得收藏可以赚取积分</text>
      </view>
    </view>
  </view>
</template>

<style scoped>
.points-page {
  min-height: 100vh;
  background: #f5f6fa;
}

.balance-card {
  margin: 24rpx 32rpx;
  background: linear-gradient(135deg, #6366f1, #818cf8);
  border-radius: 24rpx;
  padding: 48rpx 40rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: 0 8rpx 32rpx rgba(99, 102, 241, 0.25);
}

.balance-label {
  font-size: 28rpx;
  color: rgba(255, 255, 255, 0.8);
  margin-bottom: 16rpx;
}

.balance-value {
  font-size: 80rpx;
  font-weight: 800;
  color: #ffffff;
  line-height: 1;
}

.section-header {
  padding: 24rpx 32rpx 16rpx;
}

.section-title {
  font-size: 30rpx;
  font-weight: 700;
  color: #1e293b;
}

.records-list {
  padding: 0 32rpx 32rpx;
}

.record-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #ffffff;
  padding: 28rpx 28rpx;
  border-radius: 14rpx;
  margin-bottom: 16rpx;
  box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
}

.record-left {
  flex: 1;
  margin-right: 20rpx;
}

.record-reason {
  font-size: 28rpx;
  color: #1e293b;
  font-weight: 500;
  display: block;
  margin-bottom: 6rpx;
}

.record-date {
  font-size: 24rpx;
  color: #94a3b8;
  display: block;
}

.record-change {
  font-size: 34rpx;
  font-weight: 700;
  flex-shrink: 0;
}

.record-change.positive {
  color: #22c55e;
}

.record-change.negative {
  color: #ef4444;
}

.status-tip {
  text-align: center;
  padding: 40rpx 0;
  color: #94a3b8;
  font-size: 26rpx;
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 120rpx 0;
}

.empty-icon {
  font-size: 96rpx;
  margin-bottom: 24rpx;
}

.empty-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #1e293b;
  margin-bottom: 12rpx;
}

.empty-desc {
  font-size: 26rpx;
  color: #94a3b8;
}
</style>
