<template>
	<view class="page">
		<scroll-view
			scroll-y
			class="page-scroll"
			refresher-enabled
			:refresher-triggered="refreshing"
			@refresherrefresh="handleRefresh"
			@scrolltolower="loadMore"
		>
			<common-hero title="挑战杯项目库" :use-image-bg="true"></common-hero>
			<view class="hero-card">
				<view class="hero-title">创新竞赛历史项目数据库</view>
				<view class="hero-desc">
					按项目名称、学校、奖项、年份和比赛级别查看历届挑战杯案例，支持复制详情链接用于进一步追踪原始页面。
				</view>
				<view class="hero-meta">
					<view class="meta-item">
						<view class="meta-value">{{ list.length }}</view>
						<view class="meta-label">当前已加载</view>
					</view>
					<view class="meta-item">
						<view class="meta-value">{{ yearOptions.length }}</view>
						<view class="meta-label">年份筛选</view>
					</view>
					<view class="meta-item">
						<view class="meta-value">{{ levelOptions.length }}</view>
						<view class="meta-label">级别筛选</view>
					</view>
				</view>
			</view>

			<view class="filter-card">
				<view class="search-box">
					<uv-input
						v-model.trim="filters.keywords"
						class="search-input"
						placeholder="项目名称/学校/奖项"
						confirm-type="search"
						@confirm="applyFilters"
						:maxlength="-1"
						border="none"
					/>
					<view class="search-btn" @tap="applyFilters">查询</view>
				</view>

				<view class="field-row">
					<uv-input
						v-model.trim="filters.schoolName"
						class="field-input"
						placeholder="高校名称"
						confirm-type="search"
						@confirm="applyFilters"
						:maxlength="-1"
						border="none"
					/>
				</view>

				<view class="picker-row">
					<picker class="picker-item" mode="selector" :range="yearLabels" :value="yearIndex" @change="handleYearChange">
						<view class="picker-trigger">{{ filters.matchYear ? `${filters.matchYear}年` : '参赛年份' }}</view>
					</picker>
					<picker class="picker-item" mode="selector" :range="levelLabels" :value="levelIndex" @change="handleLevelChange">
						<view class="picker-trigger">{{ filters.matchLevel || '比赛级别' }}</view>
					</picker>
				</view>

				<view class="action-row">
					<view class="action-btn action-btn--primary" @tap="applyFilters">查询</view>
					<view class="action-btn" @tap="resetFilters">重置</view>
				</view>
			</view>

			<view v-if="loading && !list.length" class="state-card">
				<view class="state-title">正在加载项目库...</view>
				<view class="state-desc">请稍候，正在同步挑战杯历史项目数据。</view>
			</view>

			<view v-else-if="loadError && !list.length" class="state-card state-card--error">
				<view class="state-title">加载失败</view>
				<view class="state-desc">{{ loadError }}</view>
				<view class="state-action" @tap="loadData(true)">重新加载</view>
			</view>

			<view v-else-if="!list.length" class="state-card">
				<view class="state-title">暂无匹配项目</view>
				<view class="state-desc">请调整搜索条件后重新查询。</view>
			</view>

			<view v-else class="card-list">
				<view v-for="item in list" :key="item.id || item.sourceId" class="data-card">
					<view class="card-top">
						<view class="card-cover" :style="getCoverStyle(item.coverImage)">
							<view class="cover-tag">{{ item.matchLevel || '未分类' }}</view>
						</view>
						<view class="card-main">
							<view class="card-title">{{ item.projectName || '未命名项目' }}</view>
							<view class="card-school">{{ item.schoolName || '未知学校' }}</view>
							<view class="tag-row">
								<view class="tag-chip">{{ item.awardName || '未录入奖项' }}</view>
								<view class="tag-chip tag-chip--blue">{{ item.matchYear || '-' }}年</view>
								<view class="tag-chip tag-chip--soft">{{ item.matchTerm || '未知届次' }}</view>
							</view>
						</view>
					</view>

					<view class="info-grid">
						<view class="info-item">
							<view class="info-label">来源ID</view>
							<view class="info-value">{{ item.sourceId || '-' }}</view>
						</view>
						<view class="info-item">
							<view class="info-label">来源页码</view>
							<view class="info-value">{{ item.pageNo || '-' }}</view>
						</view>
						<view class="info-item">
							<view class="info-label">同步时间</view>
							<view class="info-value">{{ formatDateTime(item.lastSyncTime) }}</view>
						</view>
					</view>

					<view class="card-footer">
						<view class="footer-link" @tap="copyLink(item.detailUrl)">复制详情链接</view>
					</view>
				</view>
			</view>

			<view v-if="list.length" class="load-more">
				<view v-if="loadingMore" class="load-more-text">正在加载更多...</view>
				<view v-else-if="hasMore" class="load-more-text" @tap="loadMore">点击加载更多</view>
				<view v-else class="load-more-text load-more-text--end">没有更多数据了</view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	import CommonHero from '../../components/common-hero/common-hero.vue'
	import { pageTzbProjectList } from './tzb-database-service'

	const DEFAULT_FILTERS = () => ({
		keywords: '',
		schoolName: '',
		matchYear: '',
		matchLevel: ''
	})

	export default {
		components: {
			CommonHero
		},
		data() {
			return {
				loading: false,
				loadingMore: false,
				refreshing: false,
				loadError: '',
				page: 1,
				limit: 10,
				total: 0,
				hasMore: true,
				list: [],
				filters: DEFAULT_FILTERS(),
				yearOptions: [2025, 2024, 2023, 2022, 2021, 2020, 2019],
				levelOptions: ['国赛', '省赛', '校赛']
			}
		},
		computed: {
			yearLabels() {
				return ['全部年份', ...this.yearOptions.map((item) => `${item}年`)]
			},
			levelLabels() {
				return ['全部级别', ...this.levelOptions]
			},
			yearIndex() {
				if (!this.filters.matchYear) {
					return 0
				}
				const index = this.yearOptions.findIndex((item) => Number(item) === Number(this.filters.matchYear))
				return index >= 0 ? index + 1 : 0
			},
			levelIndex() {
				if (!this.filters.matchLevel) {
					return 0
				}
				const index = this.levelOptions.findIndex((item) => item === this.filters.matchLevel)
				return index >= 0 ? index + 1 : 0
			}
		},
		onLoad() {
			this.loadData(true)
		},
		methods: {
			showToast(title) {
				uni.showToast({
					title,
					icon: 'none'
				})
			},
			formatDateTime(value) {
				if (!value) {
					return '-'
				}
				const date = new Date(String(value).replace(/-/g, '/'))
				if (Number.isNaN(date.getTime())) {
					return value
				}
				const pad = (item) => String(item).padStart(2, '0')
				return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
			},
			getCoverStyle(url) {
				if (url) {
					return `background-image: linear-gradient(rgba(15, 23, 42, 0.12), rgba(15, 23, 42, 0.32)), url(${url});`
				}
				return 'background: linear-gradient(135deg, #60a5fa 0%, #2563eb 100%);'
			},
			handleYearChange(event) {
				const index = Number(event.detail.value || 0)
				this.filters.matchYear = index === 0 ? '' : this.yearOptions[index - 1]
			},
			handleLevelChange(event) {
				const index = Number(event.detail.value || 0)
				this.filters.matchLevel = index === 0 ? '' : this.levelOptions[index - 1]
			},
			handleRefresh() {
				this.refreshing = true
				this.loadData(true)
			},
			applyFilters() {
				this.loadData(true)
			},
			resetFilters() {
				this.filters = DEFAULT_FILTERS()
				this.loadData(true)
			},
			async loadData(reset = false) {
				if (this.loading || this.loadingMore) {
					if (reset) {
						this.refreshing = false
					}
					return
				}
				const nextPage = reset ? 1 : this.page
				if (!reset && !this.hasMore) {
					return
				}
				if (reset) {
					this.loading = true
					this.loadError = ''
				} else {
					this.loadingMore = true
				}
				try {
          const params = {
            page: nextPage,
            limit: this.limit,
          }
          if (this.filters.keywords) {
            params.keywords = this.filters.keywords
          }
          if (this.filters.schoolName) {
            params.schoolName = this.filters.schoolName
          }
          if (this.filters.matchYear) {
            params.matchYear = this.filters.matchYear
          }
          if (this.filters.matchLevel) {
            params.matchLevel = this.filters.matchLevel
          }

					const result = await pageTzbProjectList(params)
					const nextList = (result && result.list) || []
					const count = Number((result && result.count) || 0)
					this.total = count
					this.page = nextPage + 1
					this.list = reset ? nextList : this.list.concat(nextList)
					this.hasMore = this.list.length < count
				} catch (error) {
					this.loadError = (error && error.message) || '项目库加载失败'
					this.showToast(this.loadError)
				} finally {
					this.loading = false
					this.loadingMore = false
					this.refreshing = false
				}
			},
			loadMore() {
				if (!this.loading && !this.loadingMore && this.hasMore) {
					this.loadData(false)
				}
			},
			copyLink(url) {
				if (!url) {
					this.showToast('暂无详情链接')
					return
				}
				uni.setClipboardData({
					data: url,
					success: () => {
						this.showToast('详情链接已复制')
					}
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.page {
		min-height: 100vh;
		background:
			radial-gradient(circle at top left, rgba(37, 99, 235, 0.14), transparent 28%),
			linear-gradient(180deg, #f7fbff 0%, #fffdf8 100%);
	}

	.page-scroll {
		height: 100vh;
		//padding: 28rpx 24rpx 40rpx;
		box-sizing: border-box;
	}

	.hero-card,
	.filter-card,
	.state-card,
	.data-card {
		border-radius: 30rpx;
		box-shadow: 0 14rpx 34rpx rgba(15, 23, 42, 0.06);
	}

	.hero-card {
		padding: 34rpx 36rpx;
		border-radius: 28rpx;
		background: rgba(255, 255, 255, 0.5);
		box-shadow: 0 4rpx 12rpx 0 rgba(174, 174, 174, 0.4);
		backdrop-filter: blur(24rpx);
		-webkit-backdrop-filter: blur(24rpx);
		border: 1rpx solid rgba(255, 255, 255, 0.5);
	}

	.hero-badge {
		display: inline-flex;
		padding: 10rpx 18rpx;
		border-radius: 999rpx;
		background: rgba(20,150,242,.1);
		font-size: 22rpx;
		color: #1496f2;
	}

	.hero-title {
		margin-top: 8rpx;
		padding-left: 10rpx;
		font-size: 30rpx;
		line-height: 1.35;
		font-weight: 700;
		color: #18a0f7;
		border-left: 5px solid #0f94ef;
	}

	.hero-desc {
		margin-top: 20rpx;
		font-size: 24rpx;
		line-height: 1.8;
		color: #7f7f7f;
	}

	.hero-meta {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 16rpx;
		margin-top: 26rpx;
	}

	.meta-item {
		padding: 18rpx 16rpx;
		border-radius: 22rpx;
		background: rgba(255, 255, 255, 0.12);
	}

	.meta-value {
		font-size: 32rpx;
		font-weight: 700;
	}

	.meta-label {
		margin-top: 6rpx;
		font-size: 22rpx;
		color: rgba(255, 247, 244, 0.84);
	}

	.filter-card {
		margin-top: 22rpx;
		padding: 24rpx;
		background: rgba(255, 255, 255, 0.94);
	}

	.search-box,
	.field-input,
	.picker-trigger {
		background: #f8fbff;
		border: 1rpx solid rgba(37, 99, 235, 0.1);
	}

	.search-box {
		display: flex;
		align-items: center;
		gap: 16rpx;
		padding: 0 18rpx;
		height: 84rpx;
		border-radius: 999rpx;
	}

	:deep(.search-input.uv-input) {
		flex: 1;
		height: 100%;
		padding: 0 !important;
		background: transparent !important;
		border: 0 !important;
	}

	:deep(.search-input.uv-input .uv-input__content__field-wrapper__field) {
		font-size: 24rpx;
		color: #1f2937;
	}

	.search-btn {
		flex-shrink: 0;
		font-size: 24rpx;
		font-weight: 600;
		color: #2563eb;
	}

	.field-row,
	.picker-row,
	.action-row {
		margin-top: 16rpx;
	}

	:deep(.field-input.uv-input) {
		width: 100%;
		height: 84rpx;
		padding: 0 20rpx !important;
		border-radius: 22rpx;
		box-sizing: border-box;
		background: #f8fbff !important;
		border: 1rpx solid rgba(37, 99, 235, 0.1) !important;
	}

	:deep(.field-input.uv-input .uv-input__content__field-wrapper__field) {
		font-size: 24rpx;
		color: #1f2937;
	}

	.picker-row {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 14rpx;
	}

	.picker-item {
		display: block;
	}

	.picker-trigger {
		display: flex;
		align-items: center;
		justify-content: center;
		height: 84rpx;
		border-radius: 22rpx;
		font-size: 24rpx;
		color: #1f2937;
	}

	.action-row {
		display: flex;
		gap: 14rpx;
	}

	.action-btn {
		flex: 1;
		height: 82rpx;
		border-radius: 22rpx;
		background: #eef5ff;
		color: #2563eb;
		font-size: 24rpx;
		font-weight: 600;
		line-height: 82rpx;
		text-align: center;
	}

	.action-btn--primary {
		background: linear-gradient(135deg, #3b82f6, #2563eb);
		color: #fff;
	}

	.state-card {
		margin-top: 22rpx;
		padding: 32rpx 28rpx;
		background: rgba(255, 255, 255, 0.94);
	}

	.state-card--error {
		background: rgba(247, 250, 255, 0.98);
		border: 1rpx solid rgba(37, 99, 235, 0.16);
	}

	.state-title {
		font-size: 30rpx;
		font-weight: 700;
		color: #1f2329;
	}

	.state-desc {
		margin-top: 12rpx;
		font-size: 24rpx;
		line-height: 1.7;
		color: #6c7480;
	}

	.state-action {
		margin-top: 18rpx;
		font-size: 24rpx;
		font-weight: 600;
		color: #2563eb;
	}

	.card-list {
		display: flex;
		flex-direction: column;
		gap: 18rpx;
		margin-top: 22rpx;
	}

	.data-card {
		padding: 24rpx;
		background: rgba(255, 255, 255, 0.95);
	}

	.card-top {
		display: flex;
		gap: 18rpx;
	}

	.card-cover {
		flex-shrink: 0;
		width: 168rpx;
		height: 168rpx;
		border-radius: 24rpx;
		background-size: cover;
		background-position: center;
		overflow: hidden;
		display: flex;
		align-items: flex-start;
		justify-content: flex-start;
		padding: 16rpx;
		box-sizing: border-box;
	}

	.cover-tag {
		padding: 8rpx 14rpx;
		border-radius: 999rpx;
		background: rgba(255, 255, 255, 0.18);
		color: #fff;
		font-size: 20rpx;
		font-weight: 600;
	}

	.card-main {
		flex: 1;
		min-width: 0;
	}

	.card-title {
		font-size: 30rpx;
		font-weight: 700;
		line-height: 1.5;
		color: #0f172a;
	}

	.card-school {
		margin-top: 8rpx;
		font-size: 24rpx;
		color: #64748b;
	}

	.tag-row {
		display: flex;
		flex-wrap: wrap;
		gap: 10rpx;
		margin-top: 14rpx;
	}

	.tag-chip {
		padding: 8rpx 14rpx;
		border-radius: 999rpx;
		background: #fff4e6;
		color: #c76b11;
		font-size: 20rpx;
	}

	.tag-chip--blue {
		background: #eef5ff;
		color: #2563eb;
	}

	.tag-chip--soft {
		background: #f3f4f6;
		color: #6b7280;
	}

	.info-grid {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 14rpx;
		margin-top: 18rpx;
	}

	.info-item {
		padding: 18rpx;
		border-radius: 22rpx;
		background: #f8fbff;
	}

	.info-label {
		font-size: 20rpx;
		color: #8b94a3;
	}

	.info-value {
		margin-top: 8rpx;
		font-size: 23rpx;
		line-height: 1.6;
		color: #1f2937;
		word-break: break-all;
	}

	.card-footer {
		display: flex;
		justify-content: flex-end;
		margin-top: 18rpx;
	}

	.footer-link {
		font-size: 24rpx;
		font-weight: 600;
		color: #2563eb;
	}

	.load-more {
		padding: 28rpx 0 12rpx;
		text-align: center;
	}

	.load-more-text {
		font-size: 22rpx;
		color: #64748b;
	}

	.load-more-text--end {
		color: #94a3b8;
	}
</style>
