<template>
	<view class="records-page">
		<view v-if="records.length" class="records-list">
			<view v-for="item in records" :key="item.trade_no" class="record-card">
				<view class="record-header">
					<text class="record-merchant li-single-line">{{ item.supplier_name || '收款商家' }}</text>
					<text class="record-status" :class="statusClass(item.pay_status)">{{ formatPayStatus(item.pay_status) }}</text>
				</view>
				<view class="record-amount-row">
					<text class="record-amount-label">实付金额</text>
					<text class="record-amount">¥ {{ formatMoney(item.real_money) }}</text>
				</view>
				<view v-if="showWuyeMoney(item)" class="record-meta-row">
					<text class="record-meta-label">物业返还</text>
					<text class="record-meta-value">¥ {{ formatMoney(item.wuye_money) }}</text>
				</view>
				<view class="record-meta-row">
					<text class="record-meta-label">支付方式</text>
					<text class="record-meta-value">{{ formatPayType(item.pay_type) }}</text>
				</view>
				<view class="record-meta-row">
					<text class="record-meta-label">支付时间</text>
					<text class="record-meta-value">{{ item.pay_time || item.create_time || '-' }}</text>
				</view>
				<view class="record-footer">
					<text class="record-trade-no">单号 {{ item.trade_no }}</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 { tradeList } from '@/api/cashier';
import type { TradeListItem } from '@/api/cashier';
import { APP_CONFIG } from '@/config';

const PAGE_SIZE = 10;

const records = ref<TradeListItem[]>([]);
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 formatPayStatus = (status?: number) => {
	const map: Record<number, string> = {
		0: '未支付',
		1: '已支付',
		2: '部分退款',
		3: '全额退款',
		4: '已取消'
	};
	return map[Number(status)] || '未知状态';
};

const statusClass = (status?: number) => {
	const value = Number(status);
	if (value === 1) return 'status-success';
	if (value === 0) return 'status-pending';
	if (value === 4) return 'status-cancel';
	return 'status-refund';
};

const formatPayType = (payType?: number) => {
	const map: Record<number, string> = {
		1: '微信',
		2: '支付宝',
		3: '云闪付',
		4: '现金',
		5: '余额',
		6: '线下'
	};
	return map[Number(payType)] || '-';
};

const showWuyeMoney = (item: TradeListItem) => Number(item.wuye_money || 0) > 0;

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 tradeList({
			trade_no: '',
			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>
.records-page {
	min-height: 100vh;
	padding: 24rpx;
	background: #f4f6f8;
}

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

.record-card {
	padding: 28rpx 28rpx 24rpx;
	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-merchant {
	flex: 1;
	min-width: 0;
	color: #111827;
	font-size: 30rpx;
	font-weight: 700;
}

.record-status {
	flex-shrink: 0;
	padding: 6rpx 16rpx;
	border-radius: 999rpx;
	font-size: 22rpx;
	font-weight: 600;
}

.status-success {
	background: #e8f2ff;
	color: #1f5bd8;
}

.status-pending {
	background: #fff7e8;
	color: #d48806;
}

.status-cancel {
	background: #f3f4f6;
	color: #6b7280;
}

.status-refund {
	background: #fff1f0;
	color: #cf1322;
}

.record-amount-row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin-top: 24rpx;
}

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

.record-amount {
	color: #111827;
	font-size: 40rpx;
	font-weight: 800;
}

.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 {
	max-width: 420rpx;
	color: #374151;
	font-size: 26rpx;
	text-align: right;
}

.record-footer {
	margin-top: 22rpx;
	padding-top: 20rpx;
	border-top: 1rpx solid #eef1f5;
}

.record-trade-no {
	color: #9ca3af;
	font-size: 22rpx;
}

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

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