<template>
	<view class="boost">
		<view class="nav" :style="{paddingTop: statusBarHeight + 'px'}">
			<view class="nav-back" @tap="goBack"><text>‹</text></view>
			<view class="nav-title">学院助推赛</view>
		</view>

		<scroll-view scroll-y class="page" :style="{paddingTop: (statusBarHeight + 58) + 'px'}">
			<view class="hero">
				<view class="hero-kicker">COLLEGE ROCKET</view>
				<view class="hero-title">今天为 {{collegeName}} 推一把</view>
				<view class="rocket">
					<view class="rocket-body">🚀</view>
					<view class="rocket-line">
						<view class="rocket-progress" :style="{width: rocketPercent + '%'}"></view>
					</view>
				</view>
				<view class="hero-sub">每天1关，通关贡献学院推进值。21:30结算，前三学院成员分别获得3/2/1张星球券。</view>
			</view>

			<view class="rank-card">
				<view class="section-head">
					<text>学院推进榜</text>
					<text>我的学院第 {{home.myRankNo || '-'}} 名</text>
				</view>
				<view class="college-row" v-for="(item,i) in collegeRanks" :key="i">
					<view class="medal">{{i + 1}}</view>
					<view class="college-main">
						<text>{{item.college || item.nickname || '未知学院'}}</text>
						<view class="bar"><view :style="{width: (item.percent || 8) + '%'}"></view></view>
					</view>
					<view class="score">{{item.score || 0}}</view>
				</view>
				<view class="empty" v-if="!collegeRanks.length">今天还没有学院上榜，快来抢第一棒</view>
			</view>

			<view class="game-card">
				<view class="section-head">
					<text>今日关卡</text>
					<text>{{cleared ? '已通关' : '约2分钟'}}</text>
				</view>

				<view class="tips">
					<text>规则：点选未被压住的卡牌，底部槽内3张相同自动消除，槽满则失败。</text>
				</view>

				<view class="board">
					<view
						class="tile"
						v-for="card in visibleCards"
						:key="card.id"
						:class="{locked: isLocked(card), selected: card.selected}"
						:style="card.style"
						@tap="pickCard(card)">
						<text>{{card.icon}}</text>
					</view>
				</view>

				<view class="slot-wrap">
					<view class="slot-title">助推槽 {{slots.length}}/7</view>
					<view class="slots">
						<view class="slot" v-for="i in 7" :key="i">
							<text v-if="slots[i - 1]">{{slots[i - 1].icon}}</text>
						</view>
					</view>
				</view>

				<view class="actions">
					<view class="sub-btn" @tap="resetLevel">重开本关</view>
					<view class="main-btn" :class="{disabled: cleared || playing}" @tap="startLevel">
						{{cleared ? '今日已助推' : (session ? '继续助推' : '开始助推')}}
					</view>
				</view>
			</view>
		</scroll-view>

		<view v-if="modal.show" class="modal">
			<view class="modal-card">
				<view class="modal-title">{{modal.title}}</view>
				<view class="modal-sub">{{modal.sub}}</view>
				<view class="main-btn" @tap="closeModal">知道了</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				statusBarHeight: 20,
				userId: '',
				regionId: '',
				nickname: '',
				avatar: '',
				college: '',
				home: {},
				session: null,
				playing: false,
				cleared: false,
				startTs: 0,
				cards: [],
				slots: [],
				moveCount: 0,
				modal: { show: false, title: '', sub: '' }
			}
		},
		computed: {
			collegeName() {
				return this.college || '我的学院'
			},
			collegeRanks() {
				const list = this.home.rankList || []
				let max = 1
				list.forEach(item => {
					if ((item.score || 0) > max) max = item.score || 0
				})
				return list.map(item => {
					item.percent = Math.max(8, Math.round((item.score || 0) * 100 / max))
					return item
				})
			},
			rocketPercent() {
				let mine = null
				for (let i = 0; i < this.collegeRanks.length; i++) {
					const item = this.collegeRanks[i]
					if ((item.college || item.nickname) === this.college) {
						mine = item
						break
					}
				}
				const top = this.collegeRanks[0] || {}
				if (!mine || !top.score) return 16
				return Math.max(16, Math.min(100, Math.round((mine.score || 0) * 100 / top.score)))
			},
			visibleCards() {
				return this.cards.filter(item => !item.removed)
			}
		},
		onLoad() {
			const sys = uni.getSystemInfoSync()
			this.statusBarHeight = sys.statusBarHeight || 20
			this.userId = uni.getStorageSync('id') || ''
			this.nickname = uni.getStorageSync('nickName') || uni.getStorageSync('nickname') || ''
			this.avatar = uni.getStorageSync('avatarUrl') || uni.getStorageSync('avatar') || ''
			this.college = uni.getStorageSync('departmentName') || uni.getStorageSync('departmentTitle') || uni.getStorageSync('college') || ''
			try {
				const user = uni.getStorageSync('user')
				if (!this.college && user) {
					const u = JSON.parse(user)
					this.college = u.departmentTitle || u.departmentName || u.departmentNameStr || u.college || ''
				}
			} catch (e) {}
			try {
				const area = uni.getStorageSync('area')
				if (area) this.regionId = JSON.parse(area).id || ''
			} catch (e) {}
			this.loadHome()
			this.buildLevel()
		},
		methods: {
			loadHome() {
				this.tui.request('/app/planet/adventure/home', 'POST', {
					userId: this.userId,
					regionId: this.regionId,
					college: this.college
				}, false, false, true).then(res => {
					if (res.code == 200 && res.result) {
						this.home = res.result
						this.cleared = !res.result.freeAvailable
					}
				})
			},
			startLevel() {
				if (this.cleared || this.playing) return
				if (!this.college) {
					this.tui.toast('缺少学院信息，暂时无法参赛')
					return
				}
				this.tui.request('/app/planet/adventure/start', 'POST', {
					userId: this.userId,
					regionId: this.regionId,
					nickname: this.nickname,
					avatar: this.avatar,
					college: this.college
				}).then(res => {
					if (res.code != 200 || !res.result) {
						this.tui.toast(res.message)
						return
					}
					this.session = res.result
					this.playing = true
					this.startTs = Date.now()
					this.buildLevel()
				})
			},
			buildLevel() {
				const icons = ['🍔', '🥤', '📚', '🏀', '🎧', '🚲', '🍜', '📦', '☕', '🧋', '🎮', '🌟']
				const pool = []
				icons.forEach(icon => {
					for (let i = 0; i < 6; i++) pool.push(icon)
				})
				this.shuffle(pool)
				const cards = []
				const layerCounts = [28, 24, 20]
				let idx = 0
				layerCounts.forEach((count, layer) => {
					for (let i = 0; i < count; i++) {
						cards.push({
							id: 'c' + idx,
							icon: pool[idx],
							layer,
							x: 24 + (i % 7) * 88 + (layer * 18) + ((i % 2) * 8),
							y: 34 + Math.floor(i / 7) * 86 + (layer * 54),
							style: '',
							removed: false,
							selected: false
						})
						cards[cards.length - 1].style = `left:${cards[cards.length - 1].x}rpx;top:${cards[cards.length - 1].y}rpx;z-index:${cards[cards.length - 1].layer + 1};`
						idx++
					}
				})
				this.cards = cards
				this.slots = []
				this.moveCount = 0
			},
			pickCard(card) {
				if (!this.playing) {
					this.tui.toast('先点击开始助推')
					return
				}
				if (card.removed || card.selected || this.isLocked(card)) return
				if (this.slots.length >= 7) return
				card.selected = true
				this.slots.push(card)
				this.moveCount++
				this.tryClear(card.icon)
				if (this.cards.every(item => item.removed || item.selected)) {
					this.finishClear()
				} else if (this.slots.length >= 7) {
					this.failLevel()
				}
			},
			tryClear(icon) {
				const same = this.slots.filter(item => item.icon === icon)
				if (same.length < 3) return
				let removed = 0
				this.slots = this.slots.filter(item => {
					if (item.icon === icon && removed < 3) {
						item.removed = true
						removed++
						return false
					}
					return true
				})
			},
			isLocked(card) {
				return this.cards.some(other => {
					if (other.removed || other.selected || other.layer <= card.layer) return false
					return Math.abs(other.x - card.x) < 78 && Math.abs(other.y - card.y) < 70
				})
			},
			finishClear() {
				const duration = Math.max(20, Math.floor((Date.now() - this.startTs) / 1000))
				const progress = Math.max(100, 260 - duration + Math.max(0, 80 - this.moveCount))
				this.playing = false
				this.tui.request('/app/planet/adventure/submit', 'POST', {
					userId: this.userId,
					regionId: this.regionId,
					sessionId: this.session.sessionId,
					normalCount: this.cards.length,
					goldenCount: 1,
					diamondCount: 0,
					rainbowCount: 0,
					ticketBagCount: 0,
					propUseCount: 0,
					hitCount: 0,
					score: progress,
					durationSeconds: duration
				}).then(res => {
					if (res.code == 200) {
						this.cleared = true
						this.modal = { show: true, title: '助推成功', sub: `${this.collegeName} 获得 ${progress} 点推进值，晚上21:30争夺学院荣誉。` }
						this.loadHome()
					} else {
						this.tui.toast(res.message)
					}
				})
			},
			failLevel() {
				this.playing = false
				this.modal = { show: true, title: '槽位满了', sub: '本关失败，不消耗次数。换个顺序再推一次。' }
			},
			resetLevel() {
				if (this.cleared) return
				this.playing = false
				this.buildLevel()
			},
			closeModal() {
				this.modal.show = false
			},
			shuffle(arr) {
				for (let i = arr.length - 1; i > 0; i--) {
					const j = Math.floor(Math.random() * (i + 1))
					const t = arr[i]
					arr[i] = arr[j]
					arr[j] = t
				}
				return arr
			},
			goBack() {
				uni.navigateBack()
			}
		}
	}
</script>

<style lang="scss" scoped>
	.boost { min-height: 100vh; background: linear-gradient(155deg, #F3FFF4 0%, #EAF8FF 46%, #FFF7DE 100%); color: #12342F; }
	.nav { position: fixed; top: 0; left: 0; right: 0; height: 44px; z-index: 20; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 8rpx; background: rgba(243,255,244,0.86); }
	.nav-back { position: absolute; left: 20rpx; bottom: 0; width: 70rpx; height: 44px; display: flex; align-items: center; justify-content: center; color: #12342F; font-size: 54rpx; }
	.nav-title { color: #12342F; font-size: 34rpx; font-weight: 900; }
	.page { height: 100vh; box-sizing: border-box; padding-left: 24rpx; padding-right: 24rpx; }
	.hero, .rank-card, .game-card { margin-bottom: 24rpx; border-radius: 42rpx; background: rgba(255,255,255,0.82); padding: 30rpx; box-shadow: 0 16rpx 42rpx rgba(79,183,255,0.10); }
	.hero-kicker { color: #FF9C42; font-size: 22rpx; font-weight: 900; letter-spacing: 2rpx; }
	.hero-title { margin-top: 10rpx; font-size: 42rpx; font-weight: 900; }
	.hero-sub, .tips { margin-top: 16rpx; color: #6B817D; font-size: 24rpx; line-height: 1.55; }
	.rocket { margin-top: 22rpx; display: flex; align-items: center; gap: 16rpx; }
	.rocket-body { font-size: 56rpx; }
	.rocket-line { flex: 1; height: 18rpx; border-radius: 999rpx; background: #E6F2EF; overflow: hidden; }
	.rocket-progress { height: 100%; border-radius: 999rpx; background: linear-gradient(90deg, #35D6A6, #4FB7FF, #FFB84D); }
	.section-head { display: flex; justify-content: space-between; align-items: center; font-size: 24rpx; color: #6B817D; }
	.section-head text:first-child { color: #12342F; font-size: 31rpx; font-weight: 900; }
	.college-row { margin-top: 18rpx; display: flex; align-items: center; gap: 16rpx; }
	.medal { width: 48rpx; height: 48rpx; line-height: 48rpx; border-radius: 50%; text-align: center; background: #FFF1C7; color: #B87932; font-weight: 900; }
	.college-main { flex: 1; min-width: 0; }
	.college-main text { font-size: 25rpx; font-weight: 800; }
	.bar { margin-top: 10rpx; height: 12rpx; background: #EEF7F4; border-radius: 999rpx; overflow: hidden; }
	.bar view { height: 100%; border-radius: 999rpx; background: linear-gradient(90deg, #35D6A6, #4FB7FF); }
	.score { width: 92rpx; text-align: right; color: #22B889; font-size: 28rpx; font-weight: 900; }
	.empty { margin-top: 18rpx; color: #8AA09C; font-size: 24rpx; }
	.board { margin-top: 22rpx; height: 620rpx; border-radius: 36rpx; background: linear-gradient(155deg, rgba(234,248,255,0.9), rgba(255,248,222,0.72)); position: relative; overflow: hidden; }
	.tile { position: absolute; width: 76rpx; height: 76rpx; border-radius: 22rpx; background: #fff; display: flex; align-items: center; justify-content: center; box-shadow: 0 10rpx 22rpx rgba(66,99,94,0.12); border: 2rpx solid rgba(255,255,255,0.9); transition: transform .12s ease, opacity .12s ease; }
	.tile text { font-size: 42rpx; }
	.tile.locked { opacity: .42; background: #F2F6F5; }
	.tile.selected { opacity: 0; transform: scale(.5); pointer-events: none; }
	.slot-wrap { margin-top: 24rpx; }
	.slot-title { color: #6B817D; font-size: 24rpx; margin-bottom: 14rpx; }
	.slots { display: flex; gap: 10rpx; }
	.slot { flex: 1; height: 74rpx; border-radius: 20rpx; background: rgba(255,255,255,0.8); border: 2rpx dashed rgba(53,214,166,0.28); display: flex; align-items: center; justify-content: center; }
	.slot text { font-size: 38rpx; }
	.actions { margin-top: 28rpx; display: flex; gap: 18rpx; }
	.sub-btn, .main-btn { flex: 1; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 999rpx; font-size: 28rpx; font-weight: 900; }
	.sub-btn { background: rgba(255,255,255,0.78); color: #42635E; }
	.main-btn { background: linear-gradient(135deg, #35D6A6, #4FB7FF); color: #fff; box-shadow: 0 14rpx 34rpx rgba(53,214,166,0.2); }
	.main-btn.disabled { opacity: .45; }
	.modal { position: fixed; inset: 0; z-index: 40; background: rgba(18,52,47,0.2); display: flex; align-items: center; justify-content: center; padding: 46rpx; }
	.modal-card { width: 100%; border-radius: 42rpx; background: #fff; padding: 42rpx; text-align: center; }
	.modal-title { font-size: 40rpx; font-weight: 900; }
	.modal-sub { margin: 18rpx 0 30rpx; color: #6B817D; font-size: 26rpx; line-height: 1.55; }
</style>
