﻿<template>
	<view v-if="visible" class="popup-shell" @touchmove.stop.prevent="">
		<view class="popup-mask" @click="emit('close')"></view>
		<view class="surface-card popup-panel">
			<view class="popup-head">
				<view>
					<text class="section-title">{{ form.id ? '编辑账单' : '新增账单' }}</text>
					<text class="section-subtitle">3 步完成记录，所有数据仅保存在本机</text>
				</view>
				<text class="close-text" @click="emit('close')">关闭</text>
			</view>
			<scroll-view scroll-y class="popup-body">
				<view class="field-block">
					<text class="field-label">收支类型</text>
					<view class="pill-row">
						<view
							v-for="item in typeOptions"
							:key="item.value"
							class="pill-button"
							:class="{ active: form.type === item.value }"
							@click="form.type = item.value"
						>
							{{ item.label }}
						</view>
					</view>
				</view>

				<view class="field-block">
					<text class="field-label">金额</text>
					<view class="input-shell amount-shell">
						<text class="prefix-text">¥</text>
						<input v-model="form.amount" type="digit" placeholder="输入金额" />
					</view>
				</view>

				<view class="field-block">
					<text class="field-label">分类</text>
					<view class="chip-grid">
						<view
							v-for="item in currentCategories"
							:key="item.id"
							class="chip-item"
							:class="{ active: form.categoryId === item.id }"
							@click="form.categoryId = item.id"
						>
							<view class="chip-dot" :style="{ background: item.color }"></view>
							<text>{{ item.name }}</text>
						</view>
					</view>
				</view>

				<view class="field-block">
					<text class="field-label">账户</text>
					<view class="chip-grid">
						<view
							v-for="item in accounts"
							:key="item.id"
							class="chip-item"
							:class="{ active: form.accountId === item.id }"
							@click="form.accountId = item.id"
						>
							<view class="chip-dot" :style="{ background: item.color }"></view>
							<text>{{ item.name }}</text>
						</view>
					</view>
				</view>

				<view class="field-block">
					<text class="field-label">日期</text>
					<picker mode="date" :value="form.date" @change="onDateChange">
						<view class="input-shell picker-shell">
							<text>{{ form.date }}</text>
							<text class="tiny-text">选择</text>
						</view>
					</picker>
				</view>

				<view class="field-block">
					<text class="field-label">备注</text>
					<view class="input-shell textarea-shell">
						<textarea
							v-model="form.note"
							maxlength="40"
							placeholder="补充说明，便于后续搜索"
						></textarea>
					</view>
				</view>
			</scroll-view>
			<view class="popup-foot">
				<view class="ghost-button" @click="emit('close')">取消</view>
				<view class="primary-button save-button" @click="handleSave">保存账单</view>
			</view>
		</view>
	</view>
</template>

<script setup>
import { computed, reactive, watch } from 'vue'
import { toDateKey } from '../utils/date'

const props = defineProps({
	visible: {
		type: Boolean,
		default: false
	},
	entry: {
		type: Object,
		default: null
	},
	categories: {
		type: Object,
		required: true
	},
	accounts: {
		type: Array,
		required: true
	},
	defaultType: {
		type: String,
		default: 'expense'
	},
	initialCategoryId: {
		type: String,
		default: ''
	}
})

const emit = defineEmits(['close', 'save'])

const typeOptions = [
	{ label: '支出', value: 'expense' },
	{ label: '收入', value: 'income' }
]

const form = reactive({
	id: '',
	type: 'expense',
	amount: '',
	categoryId: '',
	accountId: '',
	date: toDateKey(),
	note: '',
	createdAt: 0
})

const currentCategories = computed(() => props.categories[form.type] || [])

function hydrateForm() {
	const source = props.entry || {}
	const nextType = source.type || props.defaultType || 'expense'
	const defaultCategory = props.initialCategoryId && (props.categories[nextType] || []).some((item) => item.id === props.initialCategoryId)
		? props.initialCategoryId
		: (props.categories[nextType]?.[0]?.id || '')

	form.id = source.id || ''
	form.type = nextType
	form.amount = source.amount ? String(source.amount) : ''
	form.categoryId = source.categoryId || defaultCategory
	form.accountId = source.accountId || props.accounts[0]?.id || ''
	form.date = source.date || toDateKey()
	form.note = source.note || ''
	form.createdAt = source.createdAt || 0
}

watch(
	() => props.visible,
	(visible) => {
		if (visible) {
			hydrateForm()
		}
	},
	{ immediate: true }
)

watch(
	() => form.type,
	(nextType) => {
		const availableIds = (props.categories[nextType] || []).map((item) => item.id)
		if (!availableIds.includes(form.categoryId)) {
			form.categoryId = availableIds[0] || ''
		}
	}
)

function onDateChange(event) {
	form.date = event.detail.value
}

function handleSave() {
	if (!Number(form.amount)) {
		uni.showToast({
			title: '请输入有效金额',
			icon: 'none'
		})
		return
	}

	if (!form.categoryId || !form.accountId) {
		uni.showToast({
			title: '请选择分类和账户',
			icon: 'none'
		})
		return
	}

	emit('save', {
		id: form.id,
		type: form.type,
		amount: Number(form.amount),
		categoryId: form.categoryId,
		accountId: form.accountId,
		date: form.date,
		note: form.note.trim(),
		createdAt: form.createdAt
	})
	emit('close')
}
</script>

<style lang="scss" scoped>
.popup-shell {
	position: fixed;
	inset: 0;
	z-index: 50;
}

.popup-mask {
	position: absolute;
	inset: 0;
	background: rgba(3, 12, 21, 0.42);
}

.popup-panel {
	position: absolute;
	left: 16rpx;
	right: 16rpx;
	bottom: 16rpx;
	max-height: 84vh;
	padding: 28rpx 28rpx 32rpx;
	display: flex;
	flex-direction: column;
	gap: 24rpx;
}

.popup-head {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16rpx;
}

.close-text {
	padding: 10rpx 0;
	font-size: 24rpx;
	color: var(--text-secondary);
}

.popup-body {
	max-height: 58vh;
}

.field-block {
	display: flex;
	flex-direction: column;
	gap: 18rpx;
	margin-bottom: 24rpx;
}

.field-label {
	font-size: 26rpx;
	font-weight: 600;
	color: var(--text-primary);
}

.pill-row,
.chip-grid {
	display: flex;
	flex-wrap: wrap;
	gap: 16rpx;
}

.chip-item {
	display: flex;
	align-items: center;
	gap: 10rpx;
	padding: 16rpx 20rpx;
	border-radius: 22rpx;
	background: var(--surface-muted);
	color: var(--text-secondary);
	font-size: 24rpx;
}

.chip-item.active {
	background: var(--brand-soft);
	color: var(--text-primary);
}

.chip-dot {
	width: 14rpx;
	height: 14rpx;
	border-radius: 50%;
}

.amount-shell {
	gap: 12rpx;
}

.prefix-text {
	font-size: 36rpx;
	font-weight: 600;
	color: var(--text-primary);
}

.picker-shell {
	justify-content: space-between;
}

.textarea-shell {
	padding: 20rpx 24rpx;
	min-height: 160rpx;
	align-items: flex-start;
}

.textarea-shell textarea {
	min-height: 120rpx;
}

.popup-foot {
	display: flex;
	align-items: center;
	gap: 16rpx;
}

.popup-foot .ghost-button {
	flex: 0 0 180rpx;
}

.save-button {
	flex: 1;
}
</style>

