<template>
	<view class="my-courses-page">
		<view class="header-wrap" :style="{ paddingTop: statusBarHeight + 'px' }">
			<view class="nav-bar" :style="{ height: navBarHeight + 'px' }">
				<text class="nav-title">&#8981; 我的课程</text>
			</view>
		</view>

		<scroll-view class="content" scroll-y :style="{ height: 'calc(100vh - ' + totalHeaderHeight + 'px)' }">
			<view class="content-inner">
				<view v-if="loading" class="loading-state">
					<text>加载中...</text>
				</view>

				<view v-for="(item, idx) in bookings" :key="idx" class="booking-card">
					<view class="booking-header">
						<text class="booking-name">{{ item.courseName }}</text>
						<view class="booking-badges">
							<text class="booking-checkin" :class="item.checkedIn ? 'checkin-done' : 'checkin-pending'">
								{{ item.checkedIn ? '&#10003; 已签到' : '&#9711; 未签到' }}
							</text>
							<text class="booking-status" :class="'status-' + item.statusValue">{{ item.statusLabel }}</text>
						</view>
					</view>
					<view class="booking-info">
						<view class="booking-row">
							<text class="booking-label">日期</text>
							<text class="booking-value">{{ item.fullDate }}</text>
						</view>
						<view class="booking-row">
							<text class="booking-label">时间</text>
							<text class="booking-value">{{ item.shortTime }} - {{ item.endShortTime }}</text>
						</view>
						<view class="booking-row" v-if="item.location">
							<text class="booking-label">地点</text>
							<text class="booking-value">{{ item.location }}</text>
						</view>
						<view class="booking-row">
							<text class="booking-label">预约时间</text>
							<text class="booking-value">{{ item.bookingTime }}</text>
						</view>
					</view>
					<view class="booking-actions" v-if="item.canCancel || item.statusValue === 0">
						<button class="signin-btn" @click="handleScanSignIn(item)" :disabled="signing === item.id">
							{{ signing === item.id ? '签到中...' : '扫码签到' }}
						</button>
						<button v-if="item.canCancel" class="cancel-btn" @click="handleCancel(item)" :disabled="cancelling">
							{{ cancelling === item.id ? '取消中...' : '取消预约' }}
						</button>
					</view>
				</view>

				<view v-if="!loading && bookings.length === 0" class="empty-state">
					<text class="empty-symbol">&#8857;</text>
					<text class="empty-text">暂无预约课程</text>
					<text class="empty-sub" @click="goToSearch">前往预约团课 &#8250;</text>
				</view>

				<view class="bottom-safe"></view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	const bookingApi = require('../../api/booking')
	const store = require('../../store/index')

	export default {
		data() {
			return {
				statusBarHeight: 0,
				navBarHeight: 44,
				totalHeaderHeight: 44,
				loading: true,
				cancelling: null,
				signing: null,
				bookings: []
			}
		},
		onLoad() {
			const systemInfo = uni.getSystemInfoSync()
			const statusBarHeight = systemInfo.statusBarHeight || 20
			let navBarHeight = 44
			// #ifdef MP-WEIXIN
			const menuButton = uni.getMenuButtonBoundingClientRect()
			if (menuButton) {
				navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height
			}
			// #endif
			this.statusBarHeight = statusBarHeight
			this.navBarHeight = navBarHeight
			this.totalHeaderHeight = statusBarHeight + navBarHeight
		},
		onShow() {
			if (!store.isLoggedIn) return
			this.loadBookings()
		},
		onPullDownRefresh() {
			this.loadBookings().finally(() => { uni.stopPullDownRefresh() })
		},
		methods: {
			goToSearch() { uni.switchTab({ url: '/pages/search/search' }) },

			async loadBookings() {
				this.loading = true
				try {
					const memberInfo = store.getMemberInfo()
					const memberId = memberInfo ? (memberInfo.memberId || memberInfo.id) : null
					if (!memberId) {
						this.bookings = []
						this.loading = false
						return
					}
					const list = await bookingApi.getMemberBookings(memberId)
					const arr = Array.isArray(list) ? list : (list && list.content ? list.content : [])

					this.bookings = arr.map(item => {
						const statusVal = item.status != null ? Number(item.status) : 0
						// booking status: 0=已预约, 1=已取消, 2=已出席, 3=缺席
						let statusLabel = '已预约'
						if (statusVal === 1) statusLabel = '已取消'
						else if (statusVal === 2) statusLabel = '已出席'
						else if (statusVal === 3) statusLabel = '缺席'

						const startTime = item.courseStartTime || ''
						const endTime = item.courseEndTime || ''
						const dt = startTime ? new Date(startTime.replace(/ /, 'T')) : null
						const edt = endTime ? new Date(endTime.replace(/ /, 'T')) : null

						const y = dt && !isNaN(dt) ? String(dt.getFullYear()) : ''
						const mo = dt && !isNaN(dt) ? String(dt.getMonth() + 1).padStart(2, '0') : ''
						const d = dt && !isNaN(dt) ? String(dt.getDate()).padStart(2, '0') : ''
						const hh = dt && !isNaN(dt) ? String(dt.getHours()).padStart(2, '0') : '--'
						const mm = dt && !isNaN(dt) ? String(dt.getMinutes()).padStart(2, '0') : '--'
						const ehh = edt && !isNaN(edt) ? String(edt.getHours()).padStart(2, '0') : '--'
						const emm = edt && !isNaN(edt) ? String(edt.getMinutes()).padStart(2, '0') : '--'

						// 格式化预约时间
						const bt = item.bookingTime || ''
						const bdt = bt ? new Date(bt.replace(/ /, 'T')) : null
						let bookingTimeStr = ''
						if (bdt && !isNaN(bdt)) {
							bookingTimeStr = String(bdt.getFullYear()) + '-' +
								String(bdt.getMonth() + 1).padStart(2, '0') + '-' +
								String(bdt.getDate()).padStart(2, '0') + ' ' +
								String(bdt.getHours()).padStart(2, '0') + ':' +
								String(bdt.getMinutes()).padStart(2, '0')
						}

						return {
							id: item.id,
							courseId: item.courseId,
							courseName: item.courseName || '未命名课程',
							location: item.location || '',
							fullDate: y + '-' + mo + '-' + d,
							shortTime: hh + ':' + mm,
							endShortTime: ehh + ':' + emm,
							bookingTime: bookingTimeStr,
							statusValue: statusVal,
							statusLabel: statusLabel,
							checkedIn: statusVal === 2,
							canCancel: statusVal === 0
						}
					})
				} catch (e) {
					console.error('加载预约列表失败:', e)
				} finally {
					this.loading = false
				}
			},

			async handleCancel(item) {
				if (this.cancelling) return
				uni.showModal({
					title: '取消预约',
					content: '确定要取消「' + item.courseName + '」的预约吗？',
					success: async (res) => {
						if (!res.confirm) return
						this.cancelling = item.id
						try {
							const memberInfo = store.getMemberInfo()
							const memberId = memberInfo ? (memberInfo.memberId || memberInfo.id) : null
							if (!memberId) {
								uni.showToast({ title: '请先登录', icon: 'none' })
								return
							}
							await bookingApi.cancelBooking(item.id, memberId)
							await this.loadBookings()
							uni.showToast({ title: '已取消', icon: 'success' })
						} catch (e) {
							console.error('取消预约失败:', e)
							const msg = (e.data && e.data.message) || '取消失败，请重试'
							uni.showToast({ title: msg, icon: 'none' })
						} finally {
							this.cancelling = null
						}
					}
				})
			},

			async handleScanSignIn(item) {
				if (this.signing) return
				// #ifdef MP-WEIXIN
				uni.scanCode({
					onlyFromCamera: true,
					scanType: ['qrCode'],
					success: async (scanRes) => {
						const scanResult = scanRes.result || ''
						let scannedCourseId = null
						// 尝试解析 QR 码内容：可能是 JSON 或纯数字
						try {
							const parsed = JSON.parse(scanResult)
							scannedCourseId = parsed.courseId || parsed.id
						} catch {
							// 非 JSON，尝试提取纯数字
							const match = scanResult.match(/\d+/)
							scannedCourseId = match ? match[0] : null
						}

						if (!scannedCourseId) {
							uni.showToast({ title: '无效的签到二维码', icon: 'none' })
							return
						}
						if (Number(scannedCourseId) !== Number(item.courseId)) {
							uni.showToast({ title: '二维码与课程不匹配', icon: 'none' })
							return
						}

						await this.doSignIn(item, scannedCourseId)
					},
					fail: (err) => {
						if (err.errMsg && err.errMsg.includes('cancel')) return
						console.error('扫码失败:', err)
						uni.showToast({ title: '扫码失败，请重试', icon: 'none' })
					}
				})
				// #endif
				// #ifndef MP-WEIXIN
				uni.showToast({ title: '请在微信小程序中使用扫码签到', icon: 'none' })
				// #endif
			},

			async doSignIn(item, scannedCourseId) {
				this.signing = item.id
				try {
					const memberInfo = store.getMemberInfo()
					const memberId = memberInfo ? (memberInfo.memberId || memberInfo.id) : null
					if (!memberId) {
						uni.showToast({ title: '请先登录', icon: 'none' })
						return
					}
					await bookingApi.signIn(Number(scannedCourseId), memberId)
					await this.loadBookings()
					uni.showToast({ title: '签到成功', icon: 'success' })
				} catch (e) {
					console.error('签到失败:', e)
					const msg = (e.data && e.data.message) || '签到失败，请重试'
					uni.showToast({ title: msg, icon: 'none' })
				} finally {
					this.signing = null
				}
			}
		}
	}
</script>

<style scoped>
	.my-courses-page { min-height: 100vh; background: #F5F7FA; overflow-x: hidden; }

	.header-wrap { background: #1A1A1A; }
	.nav-bar { background: #1A1A1A; padding: 0 20px; display: flex; align-items: center; }
	.nav-title { font-size: 18px; font-weight: 700; color: #FFFFFF; }

	.content-inner { padding: 16px; }
	.loading-state { text-align: center; padding: 40px 0; color: #7A7E84; font-size: 14px; }

	/* 预约卡片 */
	.booking-card { background: #FFFFFF; border-radius: 16px; padding: 16px; margin-bottom: 12px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
	.booking-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
	.booking-name { font-size: 16px; font-weight: 700; color: #1E1E1E; flex: 1; margin-right: 8px; }
	.booking-badges { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
	.booking-checkin { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; white-space: nowrap; }
	.checkin-pending { background: rgba(255,165,2,0.12); color: #E6A000; }
	.checkin-done { background: rgba(0,230,118,0.12); color: #00C853; }
	.booking-status { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; white-space: nowrap; }
	.status-0 { background: rgba(0,230,118,0.15); color: #00C853; }
	.status-1 { background: rgba(158,158,158,0.15); color: #9E9E9E; }
	.status-2 { background: rgba(24,144,255,0.15); color: #1890FF; }
	.status-3 { background: rgba(255,82,82,0.15); color: #FF5252; }

	.booking-info { margin-bottom: 8px; }
	.booking-row { display: flex; justify-content: space-between; padding: 4px 0; }
	.booking-label { font-size: 13px; color: #7A7E84; }
	.booking-value { font-size: 13px; color: #1E1E1E; font-weight: 500; }

	.booking-actions { display: flex; justify-content: flex-end; gap: 10px; padding-top: 8px; border-top: 1px solid #F0F0F0; }
	.signin-btn { background: transparent; border: 1px solid #00C853; color: #00C853; font-size: 13px; padding: 6px 16px; border-radius: 20px; line-height: 1.4; }
	.signin-btn::after { border: none; }
	.signin-btn[disabled] { opacity: 0.5; }
	.cancel-btn { background: transparent; border: 1px solid #FF5252; color: #FF5252; font-size: 13px; padding: 6px 16px; border-radius: 20px; line-height: 1.4; }
	.cancel-btn::after { border: none; }
	.cancel-btn[disabled] { opacity: 0.5; }

	/* 空状态 */
	.empty-state { text-align: center; padding: 60px 0; }
	.empty-symbol { font-size: 48px; color: #E0E0E0; display: block; margin-bottom: 16px; }
	.empty-text { font-size: 16px; color: #BDBDBD; display: block; margin-bottom: 12px; }
	.empty-sub { font-size: 14px; color: #00C853; }

	.bottom-safe { height: 20px; }
</style>
