<template>
	<view class="score-records-page">
		<view v-if="records.length" class="records-list">
			<view v-for="(item, index) in records" :key="recordKey(item, index)" class="record-card">
				<view class="record-header">
					<text class="record-title">{{ item.remark || formatRecordType(item) }}</text>
					<text class="record-score" :class="scoreClass(item)">{{ formatScoreChange(item) }}</text>
				</view>
				<view class="record-meta-row">
					<text class="record-meta-label">时间</text>
					<text class="record-meta-value">{{ item.create_time || '-' }}</text>
				</view>
				<view v-if="item.score !== undefined && item.score !== null && item.score !== ''" class="record-meta-row">
					<text class="record-meta-label">余额</text>
					<text class="record-meta-value">¥ {{ formatMoney(item.score) }}</text>
				</view>
			</view>
		</view>

		<view v-else-if="!loading" class="records-empty">
			<wd-status-tip :image="emptyImage" tip="暂无积分流水" />
		</view>

		<view v-if="records.length && (loading || finished)" class="records-footer">
			<wd-loadmore :state="loadMoreState" />
		</view>
	</view>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app';
import { platformScoreRecord } from '@/api/cashier';
import type { ScoreRecordItem } from '@/api/cashier';
import { APP_CONFIG } from '@/config';

const PAGE_SIZE = 10;

const records = ref<ScoreRecordItem[]>([]);
const page = ref(1);
const loading = ref(false);
const finished = ref(false);

const emptyImage = `${APP_CONFIG.RESOURCE_URL}tip/message.png`;
const loadMoreState = computed(() => (loading.value ? 'loading' : 'finished'));

const formatMoney = (value?: string | number) => {
	const amount = Number(value || 0);
	if (!Number.isFinite(amount)) return '0.00';
	return amount.toFixed(2);
};

const formatRecordType = (item: ScoreRecordItem) => {
	const type = String(item.type != null ? item.type : '');
	const map: Record<string, string> = {
		'1': '积分收入',
		'2': '积分支出',
		'3': '积分返还'
	};
	return map[type] || '积分变动';
};

const formatScoreChange = (item: ScoreRecordItem) => {
	const change = item.change_score != null ? item.change_score : item.score;
	const amount = Number(change || 0);
	if (!Number.isFinite(amount)) return '0.00';
	const prefix = amount > 0 ? '+' : '';
	return `${prefix}${amount.toFixed(2)}`;
};

const scoreClass = (item: ScoreRecordItem) => {
	const raw = item.change_score != null ? item.change_score : item.score;
	const change = Number(raw != null ? raw : 0);
	return change >= 0 ? 'score-plus' : 'score-minus';
};

const recordKey = (item: ScoreRecordItem, index: number) =>
	String(item.id != null ? item.id : `${item.create_time || 'record'}-${index}`);

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

	loading.value = true;
	const nextPage = reset ? 1 : page.value;

	try {
		const response = await platformScoreRecord({
			page: nextPage,
			limit: PAGE_SIZE
		});

		if (Number(response?.code) !== 200) {
			throw new Error(response?.msg || '获取积分流水失败');
		}

		const list = Array.isArray(response?.data) ? response.data : [];
		records.value = reset ? list : records.value.concat(list);
		page.value = nextPage + 1;
		finished.value = list.length < PAGE_SIZE;
	} catch (error: any) {
		uni.showToast({
			title: error?.message || '获取积分流水失败',
			icon: 'none'
		});
	} finally {
		loading.value = false;
		if (reset) {
			uni.stopPullDownRefresh();
		}
	}
};

onLoad(() => {
	fetchRecords(true);
});

onPullDownRefresh(() => {
	finished.value = false;
	fetchRecords(true);
});

onReachBottom(() => {
	fetchRecords(false);
});
</script>

<style lang="scss" scoped>
.score-records-page {
	min-height: 100vh;
	padding: 24rpx;
	background: #f4f6f8;
}

.records-list {
	display: flex;
	flex-direction: column;
	gap: 20rpx;
}

.record-card {
	padding: 28rpx;
	border-radius: 16rpx;
	background: #ffffff;
	box-shadow: 0 8rpx 22rpx rgba(17, 24, 39, 0.04);
}

.record-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20rpx;
}

.record-title {
	flex: 1;
	min-width: 0;
	color: #111827;
	font-size: 30rpx;
	font-weight: 700;
}

.record-score {
	flex-shrink: 0;
	font-size: 34rpx;
	font-weight: 800;
}

.score-plus {
	color: #1f5bd8;
}

.score-minus {
	color: #ef4444;
}

.record-meta-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-top: 18rpx;
}

.record-meta-label {
	color: #8b929e;
	font-size: 26rpx;
}

.record-meta-value {
	color: #374151;
	font-size: 26rpx;
}

.records-empty {
	padding-top: 300rpx;
}

.records-footer {
	padding: 12rpx 0 24rpx;
}
</style>
