<template>

	<view class="income-page">

		<!-- 筛选栏 -->

		<view class="filter-bar">

			<view class="filter-item" @click="openServiceModal">

				<text>{{ serviceFilterLabel }}</text>

				<text class="arrow">▼</text>

			</view>

			<view class="filter-item" @click="openStatusModal">

				<text>{{ statusFilterLabel }}</text>

				<text class="arrow">▼</text>

			</view>

		</view>



		<!-- 日期 & 合计 -->

		<view class="summary-row">

			<view class="date-range" @click="openDatePicker">

				<text>{{ dateRangeText }}</text>

				<text class="arrow">▼</text>

			</view>

			<text class="total" @click="onTotalClick">合计: {{ totalText }}</text>

		</view>



		<!-- 收入列表 -->

		<view class="income-list" v-if="displayList.length">

			<view class="income-card" v-for="item in displayList" :key="item.id">

				<view class="card-row card-row-top">

					<view class="category-wrap">

						<view class="category-icon"></view>

						<text class="category-name">{{ item.categoryName }}</text>

					</view>

					<text class="settle-status" :class="item.status">

						{{ item.status === 'settled' ? '已结算' : '未结算' }}

					</text>

				</view>

				<view class="card-row card-row-middle">

					<text class="service-name">{{ item.serviceName }}</text>

					<text class="income-amount">+{{ formatAmount(item.incomeAmount) }}</text>

				</view>

				<view class="card-row card-row-bottom">

					<text class="order-time">{{ item.completionTime }}</text>

					<text class="order-total">{{ formatAmount(item.orderTotal) }}</text>

				</view>

			</view>

		</view>

		<view class="empty" v-else>暂无收入记录</view>



		<!-- 服务分类弹窗 -->

		<view class="modal-mask" v-if="showServiceModal" @click="closeServiceModal">

			<view class="filter-panel" @click.stop>

				<view class="panel-header">

					<text class="panel-title">服务分类</text>

				</view>

				<view class="tag-grid">

					<view

						v-for="cat in serviceCategories"

						:key="cat.id"

						class="tag"

						:class="{ active: draftCategoryId === cat.id }"

						@click="draftCategoryId = cat.id"

					>{{ cat.name }}</view>

				</view>

				<view class="panel-btns">

					<view class="btn cancel" @click="closeServiceModal">取消</view>

					<view class="btn confirm" @click="confirmService">确定</view>

				</view>

			</view>

		</view>



		<!-- 结算状态弹窗 -->

		<view class="modal-mask" v-if="showStatusModal" @click="closeStatusModal">

			<view class="filter-panel" @click.stop>

				<view class="panel-header">

					<text class="panel-title">结算状态</text>

				</view>

				<view class="tag-row">

					<view

						v-for="opt in settleOptions"

						:key="opt.key"

						class="tag"

						:class="{ active: draftStatus === opt.key }"

						@click="draftStatus = opt.key"

					>{{ opt.label }}</view>

				</view>

				<view class="panel-btns">

					<view class="btn cancel" @click="closeStatusModal">取消</view>

					<view class="btn confirm" @click="confirmStatus">确定</view>

				</view>

			</view>

		</view>



		<!-- 日期选择 -->

		<u-datetime-picker

			:show="showDatePicker"

			v-model="pickerValue"

			mode="date"

			@confirm="onDateConfirm"

			@cancel="showDatePicker = false"

		></u-datetime-picker>

	</view>

</template>



<script>

import {

	SERVICE_CATEGORIES,

	SETTLE_STATUS_OPTIONS,

	MOCK_INCOME_LIST,

	formatIncomeTotal,

	formatDateYmd,

	getMockDateRange,

	parseTimeStr,

} from './mock.js'



export default {

	data() {

		const range = getMockDateRange()

		return {

			allList: [...MOCK_INCOME_LIST],

			serviceCategories: SERVICE_CATEGORIES,

			settleOptions: SETTLE_STATUS_OPTIONS,

			categoryId: 'all',

			settleStatus: 'all',

			draftCategoryId: 'all',

			draftStatus: 'all',

			dateStart: range.start,

			dateEnd: range.end,

			dateStartTs: range.startTs,

			dateEndTs: range.endTs,

			showServiceModal: false,

			showStatusModal: false,

			showDatePicker: false,

			pickerValue: Date.now(),

			datePickTarget: 'start',

		}

	},

	computed: {

		serviceFilterLabel() {

			if (this.categoryId === 'all') return '全部服务'

			const cat = this.serviceCategories.find(c => c.id === this.categoryId)

			return cat ? cat.name : '全部服务'

		},

		statusFilterLabel() {

			if (this.settleStatus === 'all') return '全部状态'

			const opt = this.settleOptions.find(o => o.key === this.settleStatus)

			return opt ? opt.label : '全部状态'

		},

		dateRangeText() {

			return `${this.dateStart} - ${this.dateEnd}`

		},

		displayList() {

			let list = [...this.allList]

			if (this.categoryId !== 'all') {

				list = list.filter(item => item.categoryId === this.categoryId)

			}

			if (this.settleStatus === 'settled') {

				list = list.filter(item => item.status === 'settled')

			} else if (this.settleStatus === 'unsettled') {

				list = list.filter(item => item.status === 'unsettled')

			}

			list = list.filter(item => {

				const ts = parseTimeStr(item.completionTime)

				return ts >= this.dateStartTs && ts <= this.dateEndTs + 86400000 - 1

			})

			return list.sort((a, b) => parseTimeStr(b.completionTime) - parseTimeStr(a.completionTime))

		},

		totalAmount() {

			return this.displayList.reduce((sum, item) => sum + Number(item.incomeAmount || 0), 0)

		},

		totalText() {

			return formatIncomeTotal(this.totalAmount)

		},

	},

	methods: {

		formatAmount(val) {

			return Number(val || 0).toFixed(2)

		},

		openServiceModal() {

			this.draftCategoryId = this.categoryId

			this.showServiceModal = true

		},

		closeServiceModal() {

			this.showServiceModal = false

		},

		confirmService() {

			this.categoryId = this.draftCategoryId

			this.showServiceModal = false

		},

		openStatusModal() {

			this.draftStatus = this.settleStatus

			this.showStatusModal = true

		},

		closeStatusModal() {

			this.showStatusModal = false

		},

		confirmStatus() {

			this.settleStatus = this.draftStatus

			this.showStatusModal = false

		},

		openDatePicker() {

			this.datePickTarget = 'start'

			this.pickerValue = this.dateStartTs

			this.showDatePicker = true

		},

		onDateConfirm(e) {

			const ts = e.value

			const formatted = formatDateYmd(new Date(ts))

			if (this.datePickTarget === 'start') {

				this.dateStart = formatted

				this.dateStartTs = ts

				this.datePickTarget = 'end'

				this.pickerValue = this.dateEndTs

				this.showDatePicker = false

				this.$nextTick(() => {

					this.showDatePicker = true

				})

			} else {

				this.dateEnd = formatted

				this.dateEndTs = ts

				if (this.dateStartTs > this.dateEndTs) {

					const tmpS = this.dateStart

					const tmpSt = this.dateStartTs

					this.dateStart = this.dateEnd

					this.dateEnd = tmpS

					this.dateStartTs = this.dateEndTs

					this.dateEndTs = tmpSt

				}

				this.showDatePicker = false

			}

		},

		onTotalClick() {

			uni.showToast({ title: '收入明细待对接', icon: 'none' })

		},

	},

}

</script>



<style lang="scss" scoped>

.income-page {

	min-height: 100vh;

	background: #f5f5f5;

}



.filter-bar {

	display: flex;

	background: #fff;

}



.filter-item {

	flex: 1;

	display: flex;

	align-items: center;

	justify-content: center;

	padding: 28rpx 0;

	font-size: 28rpx;

	color: #666;

}



.arrow {

	font-size: 18rpx;

	color: #bbb;

	margin-left: 8rpx;

	transform: scale(0.85);

}



.summary-row {

	display: flex;

	align-items: center;

	justify-content: space-between;

	padding: 20rpx 32rpx;

	background: #f5f5f5;

}



.date-range {

	display: flex;

	align-items: center;

	font-size: 26rpx;

	color: #666;

}



.total {

	font-size: 26rpx;

	color: #666;

}



.income-list {

	padding: 0 24rpx 32rpx;

}



.income-card {

	background: #fff;

	border-radius: 16rpx;

	padding: 28rpx 24rpx;

	margin-bottom: 16rpx;

}



.card-row {

	display: flex;

	align-items: center;

	justify-content: space-between;

}



.card-row-top {

	margin-bottom: 20rpx;

}



.category-wrap {

	display: flex;

	align-items: center;

	flex: 1;

	overflow: hidden;

	margin-right: 16rpx;

}



.category-icon {

	width: 40rpx;

	height: 40rpx;

	background: #3d4f5f;

	border-radius: 50%;

	flex-shrink: 0;

	margin-right: 12rpx;

}



.category-name {

	font-size: 28rpx;

	color: #333;

	font-weight: 500;

	overflow: hidden;

	text-overflow: ellipsis;

	white-space: nowrap;

}



.settle-status {

	flex-shrink: 0;

	font-size: 22rpx;

	padding: 4rpx 16rpx;

	border-radius: 6rpx;



	&.unsettled {

		color: #fa8c16;

		background: #fff7e6;

	}



	&.settled {

		color: #52c41a;

		background: #f6ffed;

	}

}



.card-row-middle {

	margin-bottom: 16rpx;

}



.service-name {

	flex: 1;

	font-size: 28rpx;

	color: #333;

	overflow: hidden;

	text-overflow: ellipsis;

	white-space: nowrap;

	margin-right: 16rpx;

}



.income-amount {

	flex-shrink: 0;

	font-size: 32rpx;

	color: #e54d42;

	font-weight: 600;

}



.card-row-bottom {

	align-items: flex-end;

}



.order-time {

	font-size: 24rpx;

	color: #bbb;

}



.order-total {

	font-size: 24rpx;

	color: #bbb;

}



.empty {

	text-align: center;

	padding: 120rpx 0;

	font-size: 28rpx;

	color: #999;

}



.modal-mask {

	position: fixed;

	left: 0;

	top: 0;

	right: 0;

	bottom: 0;

	background: rgba(0, 0, 0, 0.5);

	z-index: 999;

	display: flex;

	align-items: flex-end;

}



.filter-panel {

	width: 100%;

	background: #fff;

	border-radius: 24rpx 24rpx 0 0;

	padding: 0 32rpx calc(env(safe-area-inset-bottom) + 32rpx);

}



.panel-header {

	padding: 32rpx 0 28rpx;

	border-bottom: 1rpx solid #f0f0f0;

}



.panel-title {

	display: block;

	text-align: center;

	font-size: 30rpx;

	color: #333;

	font-weight: 500;

}



.tag-grid {

	display: flex;

	flex-wrap: wrap;

	gap: 20rpx;

	padding: 32rpx 0 40rpx;



	.tag {

		width: calc((100% - 40rpx) / 3);

		box-sizing: border-box;

		text-align: center;

	}

}



.tag-row {

	display: flex;

	gap: 20rpx;

	padding: 32rpx 0 40rpx;



	.tag {

		flex: 1;

		text-align: center;

	}

}



.tag {

	padding: 18rpx 0;

	font-size: 26rpx;

	color: #333;

	border: 1rpx solid #e8e8e8;

	border-radius: 8rpx;

	background: #fff;



	&.active {

		color: #333;

		border-color: #00c08b;

		background: #e8f8f4;

	}

}



.panel-btns {

	display: flex;

	gap: 24rpx;

}



.btn {

	flex: 1;

	height: 88rpx;

	line-height: 88rpx;

	text-align: center;

	border-radius: 44rpx;

	font-size: 30rpx;



	&.cancel {

		background: #f5f5f5;

		color: #333;

	}



	&.confirm {

		background: #333;

		color: #fff;

	}

}

</style>

