<template>
	<view class="plaza-container">
		<view class="header">
			<text class="title">作品广场</text>
			<text class="subtitle">发现大家发布的作品</text>
		</view>

		<scroll-view scroll-y class="works-list" @scrolltolower="loadMore">
			<view v-if="loading && works.length === 0" class="works-grid skeleton-grid">
				<view v-for="n in 6" :key="n" class="work-card skeleton-card">
					<view class="work-cover skeleton-cover"></view>
					<view class="work-info">
						<view class="skeleton-line skeleton-title"></view>
						<view class="skeleton-line skeleton-sub"></view>
						<view class="skeleton-line skeleton-sub short"></view>
					</view>
				</view>
			</view>

			<view v-else-if="!loading && works.length === 0" class="empty-box">
				<text class="empty-icon">🖼️</text>
				<text class="empty-text">暂无作品</text>
				<text class="empty-hint">快去发布你的第一个作品吧</text>
			</view>

			<view v-else class="works-grid">
				<view
					v-for="work in works"
					:key="work.id"
					class="work-card"
					@click="viewWork(work)"
				>
					<view class="work-cover">
						<image v-if="work.coverUrl" :src="work.coverUrl" mode="aspectFill" class="cover-img" />
						<view v-else class="cover-placeholder">
							<text class="placeholder-icon">🎬</text>
						</view>
						<view class="work-type">{{ work.workTypeLabel }}</view>
						<!-- AI生成提示标签 -->
						<view class="ai-tag">
							<text class="ai-tag-text">AI生成</text>
						</view>
					</view>
					<view class="work-info">
						<text class="work-title">{{ work.title }}</text>
						<text class="work-author">{{ work.userNickname || '匿名' }}</text>
						<text class="work-time">{{ formatTime(work.publishedAt || work.createdAt) }}</text>
						<view class="work-actions" @click.stop>
							<view class="like-btn" :class="{ liked: work.liked }" @click.stop="toggleLike(work)">
								<text class="like-icon">{{ work.liked ? '❤️' : '🤍' }}</text>
								<text class="like-count">{{ work.likeCount || 0 }}</text>
							</view>
						</view>
					</view>
				</view>
			</view>

			<view v-if="loading && works.length > 0" class="loading-more">
				<text class="loading-more-text">⏳ 加载更多...</text>
			</view>
			<view v-if="!hasMore && works.length > 0" class="no-more">
				<text class="no-more-text">没有更多了</text>
			</view>
		</scroll-view>
	</view>
</template>

<script>
import { API_BASE, API_ENDPOINTS } from '@/config/api.js';

export default {
	data() {
		return {
			API_BASE,
			works: [],
			page: 0,
			size: 10,
			loading: false,
			hasMore: true,
			loadedOnce: false,
			hasCachedWorks: false,
			enableVideoPreload: false,
			preloadQueue: [],
			activePreloads: 0,
			maxConcurrentPreloads: 2,
			preloadingKeys: {}
		};
	},
	onLoad() {
		try {
			const cached = uni.getStorageSync('plaza_works_cache_v1');
			if (Array.isArray(cached) && cached.length > 0) {
				this.works = cached;
				this.hasCachedWorks = true;
				this.loadedOnce = true;
			}
		} catch (e) {
			this.hasCachedWorks = false;
		}
		this.loadWorks(true);
	},
	onShow() {
		if (!this.loadedOnce || this.works.length === 0) {
			this.loadWorks(true);
		}
	},
	methods: {
		normalizeMediaUrl(url) {
			if (!url) return url;
			if (url.startsWith('/')) {
				return `${this.API_BASE}${url}`;
			}
			if (url.startsWith('http://115.190.167.176:20002')) {
				return url.replace('http://115.190.167.176:20002', this.API_BASE);
			}
			return url;
		},
		
		generateCacheKey(url) {
			let hash = 0;
			for (let i = 0; i < url.length; i++) {
				const char = url.charCodeAt(i);
				hash = ((hash << 5) - hash) + char;
				hash = hash & hash;
			}
			return 'video_' + Math.abs(hash);
		},
		
		enqueuePreload(url) {
			if (!this.enableVideoPreload) return;
			if (!url) return;
			const cacheKey = this.generateCacheKey(url);
			if (this.preloadingKeys[cacheKey]) return;
			const cachedPath = uni.getStorageSync(cacheKey);
			if (cachedPath) {
				return;
			}
			this.preloadingKeys[cacheKey] = true;
			this.preloadQueue.push({ url, cacheKey });
			this.processPreloadQueue();
		},
		
		processPreloadQueue() {
			while (this.activePreloads < this.maxConcurrentPreloads && this.preloadQueue.length > 0) {
				const item = this.preloadQueue.shift();
				this.activePreloads += 1;
				this.preloadVideoToCache(item.url, item.cacheKey)
					.finally(() => {
						this.activePreloads = Math.max(0, this.activePreloads - 1);
						this.processPreloadQueue();
					});
			}
		},
		
		preloadVideoToCache(url, cacheKey) {
			return new Promise((resolve) => {
				uni.downloadFile({
					url,
					timeout: 60000,
					success: (res) => {
						if (res.statusCode !== 200) {
							resolve();
							return;
						}
						uni.saveFile({
							tempFilePath: res.tempFilePath,
							success: (saveRes) => {
								const savedPath = saveRes.savedFilePath;
								uni.setStorageSync(cacheKey, savedPath);
								const cacheInfo = uni.getStorageSync('video_cache_info') || {};
								cacheInfo[cacheKey] = {
									path: savedPath,
									url,
									time: Date.now()
								};
								uni.setStorageSync('video_cache_info', cacheInfo);
								resolve();
							},
							fail: () => {
								resolve();
							}
						});
					},
					fail: () => {
						resolve();
					},
					complete: () => {
						if (this.preloadingKeys && cacheKey) {
							this.preloadingKeys[cacheKey] = false;
						}
					}
				});
			});
		},
		
		preloadWorks(works) {
			if (!Array.isArray(works) || works.length === 0) return;
			uni.getNetworkType({
				success: (res) => {
					if (!res || res.networkType !== 'wifi') {
						return;
					}
					works.forEach((w) => {
						if (w && w.contentUrl) {
							this.enqueuePreload(w.contentUrl);
						}
					});
				},
				fail: () => {
					return;
				}
			});
		},
		
		getWorkTypeLabel(type) {
			const map = {
				VOICE_CLONE: '声音克隆',
				PHOTO_REVIVAL: '照片复活',
				VIDEO_CALL: '视频对话'
			};
			return map[type] || '作品';
		},

		toggleLike(work) {
			const token = uni.getStorageSync('token') || '';
			const userId = uni.getStorageSync('userId') || '';
			if (!userId) {
				uni.showToast({ title: '请先登录', icon: 'none' });
				return;
			}
			uni.request({
				url: `${this.API_BASE}/api/works/${work.id}/like`,
				method: 'POST',
				header: {
					'X-User-Id': userId,
					'Authorization': token ? `Bearer ${token}` : ''
				},
				success: (res) => {
					if (res.statusCode === 200 && res.data && res.data.success && res.data.data) {
						work.liked = !!res.data.data.liked;
						work.likeCount = res.data.data.likeCount || 0;
						return;
					}
					uni.showToast({ title: res.data?.message || '操作失败', icon: 'none' });
				},
				fail: () => {
					uni.showToast({ title: '操作失败', icon: 'none' });
				}
			});
		},

		formatTime(value) {
			if (!value) return '';
			const d = new Date(value);
			if (Number.isNaN(d.getTime())) return String(value);
			const pad = (n) => (n < 10 ? `0${n}` : `${n}`);
			return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
		},

		loadMore() {
			if (this.loading || !this.hasMore) return;
			this.loadWorks(false);
		},

		loadWorks(reset) {
			if (this.loading) return;
			this.loading = true;

			const token = uni.getStorageSync('token') || '';
			const userId = uni.getStorageSync('userId') || '';

			if (reset) {
				this.page = 0;
				this.hasMore = true;
				if (!this.hasCachedWorks) {
					this.works = [];
				}
			}

			uni.request({
				url: `${this.API_BASE}${API_ENDPOINTS.works.plaza}?page=${this.page}&size=${this.size}`,
				method: 'GET',
				header: {
					'X-User-Id': userId,
					'Authorization': token ? `Bearer ${token}` : ''
				},
				success: (res) => {
					if (res.statusCode === 200 && res.data) {
						const content = res.data.content || [];
						const mapped = content.map((w) => ({
							...w,
							coverUrl: this.normalizeMediaUrl(w.coverUrl),
							contentUrl: this.normalizeMediaUrl(w.contentUrl),
							audioUrl: this.normalizeMediaUrl(w.audioUrl),
							workTypeLabel: this.getWorkTypeLabel(w.workType),
							likeCount: w.likeCount || 0,
							liked: !!w.liked
						}));
						if (reset) {
							this.works = mapped;
							this.hasCachedWorks = false;
							try {
								uni.setStorageSync('plaza_works_cache_v1', mapped);
							} catch (e) {}
						} else {
							this.works = this.works.concat(mapped);
						}
						this.page += 1;
						this.hasMore = !res.data.last;
						this.loadedOnce = true;
						return;
					}
					uni.showToast({
						title: `加载失败(${res.statusCode})`,
						icon: 'none'
					});
				},
				fail: () => {
					uni.showToast({
						title: '加载失败',
						icon: 'none'
					});
				},
				complete: () => {
					this.loading = false;
				}
			});
		},

		viewWork(work) {
			if (!work || (!work.contentUrl && !work.editedVideoUrl && !work.edited_video_url)) {
				uni.showToast({ title: '作品不可用', icon: 'none' });
				return;
			}
			const videoUrl = work.editedVideoUrl || work.edited_video_url || work.contentUrl;
			let url = `/pages/video-player/video-player?audioInVideo=1&url=${encodeURIComponent(videoUrl)}&title=${encodeURIComponent(work.title || '作品')}`;
			uni.navigateTo({ url });
		}
	}
};
</script>

<style lang="scss" scoped>
.plaza-container {
	min-height: 100vh;
	background: #FDF8F2;
	display: flex;
	flex-direction: column;
}

.header {
	padding: 32upx 32upx 20upx 40upx;

	.title {
		font-size: 44upx;
		font-weight: 700;
		color: #8B7355;
		display: block;
		margin-bottom: 8upx;
	}

	.subtitle {
		font-size: 24upx;
		color: #999;
		display: block;
	}
}

.works-list {
	flex: 1;
	padding: 0 24upx 40upx;
	box-sizing: border-box;
}

.loading-box,
.empty-box {
	padding: 200upx 40upx;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.loading-text {
	font-size: 28upx;
	color: #999;
}

.empty-icon {
	font-size: 120upx;
	margin-bottom: 30upx;
	opacity: 0.5;
}

.empty-text {
	font-size: 32upx;
	color: #666;
	margin-bottom: 16upx;
}

.empty-hint {
	font-size: 26upx;
	color: #999;
}

.works-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 16upx;
}

 .skeleton-grid {
 	padding-top: 16upx;
 }

 .skeleton-card {
 	background: white;
 }

 .skeleton-cover {
 	position: relative;
 	width: 100%;
 	padding-top: 150%;
 	background: #f1f1f1;
 }

 .skeleton-line {
 	height: 22upx;
 	background: #f1f1f1;
 	border-radius: 10upx;
 	margin-top: 12upx;
 }

 .skeleton-title {
 	height: 26upx;
 	margin-top: 0;
 }

 .skeleton-sub {
 	height: 20upx;
 }

 .skeleton-sub.short {
 	width: 60%;
 }

.work-card {
	background: white;
	border-radius: 16upx;
	overflow: hidden;
	box-shadow: 0 4upx 12upx rgba(0, 0, 0, 0.06);
	transition: all 0.3s;

	&:active {
		transform: translateY(-4upx);
		box-shadow: 0 8upx 20upx rgba(0, 0, 0, 0.12);
	}
}

.work-cover {
	position: relative;
	width: 100%;
	padding-top: 150%;
	overflow: hidden;
	background: #F5F5F5;

	.cover-img {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.cover-placeholder {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.placeholder-icon {
		font-size: 60upx;
		color: #ccc;
	}

	.work-type {
		position: absolute;
		top: 12upx;
		right: 12upx;
		padding: 6upx 16upx;
		background: rgba(0, 0, 0, 0.6);
		color: white;
		font-size: 20upx;
		border-radius: 20upx;
	}

	/* AI生成提示标签 */
	.ai-tag {
		position: absolute;
		top: 12upx;
		left: 12upx;
		padding: 6upx 16upx;
		background: rgba(255, 165, 0, 0.85);
		color: white;
		font-size: 20upx;
		border-radius: 20upx;
		font-weight: 500;
	}
}

.work-info {
	padding: 20upx;

	.work-title {
		display: block;
		font-size: 28upx;
		font-weight: bold;
		color: #333;
		margin-bottom: 12upx;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.work-author {
		display: block;
		font-size: 22upx;
		color: #666;
		margin-bottom: 10upx;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
	}

	.work-time {
		display: block;
		font-size: 22upx;
		color: #999;
	}
}

.work-actions {
	margin-top: 14upx;
	display: flex;
	justify-content: flex-end;
}

.like-btn {
	display: flex;
	align-items: center;
	gap: 10upx;
	padding: 10upx 16upx;
	border-radius: 999upx;
	background: rgba(139, 115, 85, 0.08);
}

.like-btn.liked {
	background: rgba(220, 60, 90, 0.10);
}

.like-icon {
	font-size: 26upx;
}

.like-count {
	font-size: 22upx;
	color: #666;
}

.loading-more-text,
.no-more-text {
	font-size: 24upx;
	color: #999;
}
</style>
