<template>
	<view class="post-detail-page">
		<!-- 加载中状态 -->
		<view class="loading-container" v-if="isLoading">
			<view class="loading-spinner"></view>
			<text class="loading-text">加载中...</text>
		</view>

		<!-- 内容区域 -->
		<scroll-view class="content-scroll" scroll-y v-else>
			<!-- 视频播放器区域（优先显示） -->
			<view class="video-player-section" v-if="postData.videoUrl">
				<video 
					class="video-player"
					:src="postData.videoUrl" 
					:poster="postData.images && postData.images.length > 0 ? postData.images[0] : ''"
					controls
					objectFit="contain"
					show-center-play-btn
					enable-play-gesture
				></video>
				<!-- 餐次标签 -->
				<view class="meal-tag" v-if="postData.mealType">
					<text class="meal-icon">{{ getMealIcon(postData.mealType) }}</text>
					<text class="meal-text">{{ getMealTypeLabel(postData.mealType) }}</text>
				</view>
			</view>
			
			<!-- 图片轮播区域（无视频时显示） -->
			<view class="image-carousel" v-else-if="postData.images && postData.images.length > 0">
				<swiper 
					class="swiper" 
					:indicator-dots="postData.images.length > 1" 
					:autoplay="false"
					:current="currentImageIndex"
					@change="onImageChange"
					indicator-color="rgba(255,255,255,0.5)"
					indicator-active-color="#ffffff"
				>
					<swiper-item v-for="(image, index) in postData.images" :key="index">
						<image class="carousel-image" :src="image" mode="aspectFill" @click="previewImage(index)"></image>
					</swiper-item>
				</swiper>
				<!-- 餐次标签 -->
				<view class="meal-tag" v-if="postData.mealType">
					<text class="meal-icon">{{ getMealIcon(postData.mealType) }}</text>
					<text class="meal-text">{{ getMealTypeLabel(postData.mealType) }}</text>
				</view>
				<!-- 图片页码 -->
				<view class="image-counter" v-if="postData.images.length > 1">
					{{ currentImageIndex + 1 }} / {{ postData.images.length }}
				</view>
			</view>

			<!-- 帖子内容区域 -->
			<view class="post-content-section">
				<!-- 无图片时显示类型标签 -->
				<view class="type-tag-row" v-if="!postData.images || postData.images.length === 0">
					<view class="type-tag">{{ getMealTypeLabel(postData.mealType) }}</view>
				</view>

				<!-- 标题和分数 -->
				<view class="title-row">
					<view class="post-title">{{ postData.title }}</view>
					<view class="score-badge" v-if="postData.score > 0">
						<text>{{ postData.score }}分</text>
					</view>
				</view>

				<!-- 帖子描述 -->
				<view class="post-description" v-if="postData.description">
					<text>{{ postData.description }}</text>
				</view>

				<!-- 标签列表 -->
				<view class="tag-list" v-if="postData.tags && postData.tags.length > 0">
					<view 
						class="tag-item" 
						v-for="(tag, index) in postData.tags" 
						:key="index"
					>
						{{ tag }}
					</view>
				</view>

				<!-- 作者信息 -->
				<view class="author-section">
					<view class="author-info">
						<view class="author-avatar">
							<image 
								v-if="postData.author.avatar && postData.author.avatar.startsWith('http')" 
								class="avatar-img" 
								:src="postData.author.avatar" 
								mode="aspectFill"
							></image>
							<text v-else class="avatar-icon">👤</text>
						</view>
						<view class="author-details">
							<view class="author-name">{{ postData.author.name }}</view>
							<view class="post-time">{{ postData.author.time }}</view>
						</view>
					</view>
					<view 
						class="follow-btn" 
						:class="{ followed: isFollowed }"
						@click="toggleFollow"
					>
						<text>{{ isFollowed ? '已关注' : '+ 关注' }}</text>
					</view>
				</view>
			</view>

			<!-- 营养统计卡片：仅当 nutritionStats.length > 0 时展示，不依赖后端字段存在性 -->
			<view class="nutrition-stats-card" v-if="nutritionStats.length > 0">
				<view class="stats-header">
					<view class="stats-title">
						<text class="title-icon">📊</text>
						<text class="title-text">营养统计</text>
					</view>
					<view class="stats-unit">
						<text>基于100g</text>
					</view>
				</view>
				<view class="stats-grid">
					<view class="stat-item" v-for="(stat, index) in nutritionStats" :key="index">
						<view class="stat-value">{{ stat.value }}</view>
						<view class="stat-label">{{ stat.label }}</view>
					</view>
				</view>
			</view>

			<!-- T08/T09: 无营养数据时展示「AI 补充营养」按钮 -->
			<view class="nutrition-fill-row" v-else-if="!isLoading && (postData.description || postData.title)">
				<button 
					class="ai-fill-btn" 
					:disabled="aiNutritionFilling" 
					@click="fillNutritionByAi"
				>
					<text v-if="!aiNutritionFilling">🤖 AI 补充营养</text>
					<text v-else>估算中...</text>
				</button>
			</view>

			<!-- AI营养师点评 -->
			<view class="ai-comment-card" v-if="postData.aiComment">
				<view class="ai-header">
					<view class="ai-avatar">AI</view>
					<view class="ai-info">
						<view class="ai-name-row">
							<text class="ai-name">营养师点评</text>
							<text class="ai-verified">已认证</text>
						</view>
						<view class="ai-comment-text">
							{{ postData.aiComment }}
						</view>
					</view>
				</view>
			</view>

			<!-- 一键借鉴打卡按钮 -->
			<view class="copy-checkin-btn" @click="handleCopyCheckin">
				<text class="btn-icon">🎬</text>
				<text class="btn-text">一键借鉴打卡</text>
			</view>

			<!-- 分隔线 -->
			<view class="divider"></view>

			<!-- 评论区域 -->
			<view class="comments-section">
				<view class="comments-header">
					<text class="comments-icon">💬</text>
					<text class="comments-title">全部评论 {{ postData.comments.length }}</text>
				</view>
				<view class="comments-list">
					<view 
						class="comment-item" 
						v-for="(comment, index) in postData.comments" 
						:key="index"
					>
						<view class="comment-avatar">
							<text>{{ comment.avatar }}</text>
						</view>
						<view class="comment-content">
							<view class="comment-header">
								<text class="comment-name">{{ comment.name }}</text>
								<text class="comment-time">{{ comment.time }}</text>
							</view>
							<view class="comment-text">{{ comment.text }}</view>
							<view class="comment-actions">
								<view class="like-btn" @click="toggleCommentLike(comment, index)">
									<text class="like-icon">❤️</text>
									<text class="like-count">{{ comment.likeCount }}</text>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>

			<!-- 相关推荐 -->
			<view class="related-section">
				<view class="related-header">
					<text class="related-icon">✨</text>
					<text class="related-title">相关推荐</text>
				</view>
				<view class="related-list">
					<view 
						class="related-item" 
						v-for="(item, index) in relatedPosts" 
						:key="index"
						@click="goToRelatedPost(item)"
					>
						<image class="related-image" :src="item.image" mode="aspectFill"></image>
					</view>
				</view>
			</view>

			<!-- 底部安全距离 -->
			<view class="safe-bottom"></view>
		</scroll-view>

		<!-- 底部操作栏 -->
		<view class="bottom-bar">
			<view class="input-box" @click="focusInput">
				<text class="input-placeholder">说点什么...</text>
			</view>
			<view class="action-buttons">
				<view class="action-btn-item" @click="toggleLike">
					<text class="action-icon">❤️</text>
					<text class="action-count">{{ postData.likeCount }}</text>
				</view>
				<view class="action-btn-item" @click="toggleFavorite">
					<text class="action-icon">⭐</text>
					<text class="action-count">{{ postData.favoriteCount }}</text>
				</view>
				<!-- <view class="action-btn-item" @click="handleShare">
					<text class="action-icon">📤</text>
				</view> -->
			</view>
		</view>
	</view>
</template>

<script>
import { 
	getCommunityDetail, 
	getCheckinDetail,
	getAiNutritionFill,
	fillPostNutrition,
	toggleLike as apiToggleLike, 
	toggleCollect, 
	toggleFollow as apiToggleFollow,
	getCommentList,
	addComment,
	getCommunityList
} from '@/api/tool.js'
import { checkLogin, toLogin } from '@/libs/login.js'

export default {
	data() {
		return {
			postId: null,
			currentImageIndex: 0,
			isLoading: true,
			isFollowed: false,
			isLiked: false,
			isCollected: false,
			postData: {
				id: null,
				images: [],
				mealType: '',
				title: '',
				score: 0,
				description: '',
				tags: [],
				author: {
					id: null,
					avatar: '👤',
					name: '',
					time: ''
				},
				nutritionStats: [],
				aiComment: '',
				comments: [],
				likeCount: 0,
				favoriteCount: 0,
				commentCount: 0,
				videoUrl: null,
				videoStatus: null,
				hasVideo: false
			},
			relatedPosts: [],
			commentPage: 1,
			commentLimit: 10,
			hasMoreComments: true,
			isLoadingComments: false,
			showCommentInput: false,
			commentText: '',
			aiNutritionFilling: false
		}
	},
	computed: {
		// 营养统计数组，用于卡片显示与列表渲染（单一数据源，避免未定义）
		nutritionStats() {
			const stats = this.postData && this.postData.nutritionStats
			return Array.isArray(stats) ? stats : []
		}
	},
	onLoad(options) {
		if (options.id) {
			// Ensure postId is number for API calls (URL params are strings)
			this.postId = parseInt(options.id, 10) || options.id
			this.loadPostData(this.postId)
		}
	},
	methods: {
		// 获取餐次类型中文标签
		getMealTypeLabel(mealType) {
			if (!mealType) return '分享'
			const map = { breakfast:'早餐', lunch:'午餐', dinner:'晚餐', snack:'加餐', share:'分享', checkin:'打卡' }
			return map[String(mealType).toLowerCase()] ?? '分享'
		},

		// 加载帖子详情
		async loadPostData(id) {
			this.isLoading = true
			
			try {
				const res = await getCommunityDetail(id)
				const data = res.data || res
				
				// 格式化帖子数据
				this.formatPostData(data)

				// 若详情接口未返回营养数据且有关联打卡记录，则根据打卡详情补充营养统计（等待完成后再结束加载）
				const checkInId = data.checkInRecordId != null ? (Number(data.checkInRecordId) || data.checkInRecordId) : null
				if (this.postData.nutritionStats.length === 0 && checkInId != null) {
					await this.fillNutritionStatsFromCheckin(checkInId)
				}
				// T07: 营养仍为空时调用服务端填充接口
				if (this.postData.nutritionStats.length === 0) {
					await this.fillNutritionFromServer()
				}
				
				// 同步状态
				this.isLiked = data.isLiked || false
				this.isCollected = data.isCollected || false
				this.isFollowed = data.isFollowed || false
				
				// 加载评论
				this.loadComments()
				
				// 加载相关推荐
				this.loadRelatedPosts()
				
			} catch (error) {
				console.error('加载帖子详情失败:', error)
				uni.showToast({
					title: '加载失败，请重试',
					icon: 'none'
				})
			} finally {
				this.isLoading = false
			}
		},
		
		/**
		 * 从详情接口返回的数据中构建 nutritionStats 数组
		 * 支持：nutritionStats/nutrition_stats 数组、nutritionDataJson/nutrition_data_json、dietaryData/mealData 等
		 */
		buildNutritionStatsFromDetailData(data) {
			if (!data) return []

			// 1) 后端直接返回的 stat 数组（兼容不同命名）
			const rawStats = data.nutritionStats || data.nutrition_stats
			if (Array.isArray(rawStats) && rawStats.length > 0) {
				return rawStats.map(s => ({
					label: s.label || s.name || '',
					value: s.value != null ? String(s.value) : '-'
				})).filter(s => s.label)
			}

			// 2) nutritionDataJson / nutrition_data_json（兼容后端驼峰与下划线；含 fill-nutrition 的 energyKcal/proteinG/potassiumMg/phosphorusMg、打卡字段 actualEnergy/actualProtein）
			const jsonRaw = data.nutritionDataJson || data.nutrition_data_json
			if (jsonRaw) {
				try {
					const nutritionData = typeof jsonRaw === 'string' ? JSON.parse(jsonRaw) : jsonRaw
					if (!nutritionData || typeof nutritionData !== 'object') return []
					// 2a) 若为数组格式 [{label, value}, ...]，直接使用
					if (Array.isArray(nutritionData) && nutritionData.length > 0) {
						return nutritionData.map(s => ({
							label: s.label || s.name || '',
							value: s.value != null ? String(s.value) : '-'
						})).filter(s => s.label)
					}
					// 2b) 对象格式：兼容后端 fill-nutrition 的 energyKcal/proteinG/potassiumMg/phosphorusMg 及常见命名
					return this.buildNutritionStatsFromNutritionObject(nutritionData)
				} catch (e) {
					// ignore
				}
			}

			// 3) dietaryData / mealData / dietary_data / meal_data（饮食打卡对象）
			const dietary = data.dietaryData || data.dietary_data || data.mealData || data.meal_data
			if (dietary) {
				const obj = typeof dietary === 'string' ? (() => { try { return JSON.parse(dietary) } catch (_) { return null } })() : dietary
				if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
					const statsFromObj = this.buildNutritionStatsFromNutritionObject(obj)
					if (statsFromObj.length > 0) return statsFromObj
				}
			}

			// 4) data 本身为营养对象（如 fill-nutrition 接口直接返回的 { energyKcal, proteinG, potassiumMg, phosphorusMg }）
			if (data && typeof data === 'object' && !Array.isArray(data) && (data.energyKcal != null || data.proteinG != null || data.actualEnergy != null || data.actualProtein != null || data.calories != null || data.protein != null)) {
				const statsFromData = this.buildNutritionStatsFromNutritionObject(data)
				if (statsFromData.length > 0) return statsFromData
			}

			return []
		},

		/** 从单一营养对象构建 [{label, value}, ...]，统一兼容 energyKcal/proteinG/potassiumMg/phosphorusMg 及 calories/protein 等命名 */
		buildNutritionStatsFromNutritionObject(obj) {
			if (!obj || typeof obj !== 'object') return []
			const cal = obj.energyKcal ?? obj.calories ?? obj.energy ?? obj.calorie ?? obj.actualEnergy
			const pro = obj.proteinG ?? obj.protein ?? obj.proteins ?? obj.actualProtein
			const pot = obj.potassiumMg ?? obj.potassium ?? obj.k
			const pho = obj.phosphorusMg ?? obj.phosphorus ?? obj.p
			return [
				{ label: '热量(kcal)', value: cal != null ? String(cal) : '-' },
				{ label: '蛋白质', value: this.formatNutritionValue(pro, 'g') },
				{ label: '钾', value: pot != null ? (typeof pot === 'number' ? pot + 'mg' : String(pot)) : '-' },
				{ label: '磷', value: pho != null ? (typeof pho === 'number' ? pho + 'mg' : String(pho)) : '-' }
			]
		},

		/** 格式化营养素显示值（兼容 number/string/BigDecimal 等） */
		formatNutritionValue(val, unit) {
			if (val == null || val === '') return '-'
			const str = typeof val === 'number' ? String(val) : String(val)
			return str === '' || str === 'undefined' || str === 'null' ? '-' : (unit ? str + unit : str)
		},

		/**
		 * 根据打卡详情接口返回的数据构建 nutritionStats（蛋白质、热量、钾、磷）
		 */
		buildNutritionStatsFromCheckinDetail(detail) {
			if (!detail || typeof detail !== 'object') return []
			const energy = detail.actualEnergy ?? detail.energy
			const protein = detail.actualProtein ?? detail.protein
			return [
				{ label: '热量(kcal)', value: energy != null ? String(energy) : '-' },
				{ label: '蛋白质', value: this.formatNutritionValue(protein, 'g') },
				{ label: '钾', value: '-' },
				{ label: '磷', value: '-' }
			]
		},

		/**
		 * 根据打卡记录 ID 拉取打卡详情，并填充 postData.nutritionStats（不阻塞主流程）
		 */
		async fillNutritionStatsFromCheckin(checkInRecordId) {
			try {
				const res = await getCheckinDetail(checkInRecordId)
				const detail = res.data || res
				const stats = this.buildNutritionStatsFromCheckinDetail(detail)
				if (stats.length > 0) {
					this.postData.nutritionStats = stats
				}
			} catch (e) {
				console.warn('拉取打卡详情补充营养数据失败:', e)
			}
		},

		/**
		 * T07: 调用服务端 fill-nutrition 接口，根据帖子内容补充营养并更新本地展示
		 */
		async fillNutritionFromServer() {
			if (!this.postId) return
			try {
				const res = await fillPostNutrition(this.postId)
				const data = res.data || res
				if (!data) return
				const stats = this.buildNutritionStatsFromDetailData(data)
				if (stats.length > 0) {
					this.postData.nutritionStats = stats
				}
			} catch (e) {
				console.warn('服务端填充帖子营养失败:', e)
			}
		},

		/**
		 * T08/T09: 用 AI 根据帖子描述估算营养并填充 nutritionStats
		 */
		async fillNutritionByAi() {
			const text = (this.postData.description || this.postData.title || '').trim()
			if (!text) {
				uni.showToast({ title: '暂无描述可估算', icon: 'none' })
				return
			}
			this.aiNutritionFilling = true
			try {
				const res = await getAiNutritionFill(text)
				const data = (res && res.data) ? res.data : res
				if (!data || typeof data !== 'object') {
					uni.showToast({ title: 'AI 估算暂无结果', icon: 'none' })
					return
				}
				const energy = data.energyKcal != null ? String(data.energyKcal) : '-'
				const protein = this.formatNutritionValue(data.proteinG, 'g')
				const potassium = data.potassiumMg != null ? String(data.potassiumMg) + 'mg' : '-'
				const phosphorus = data.phosphorusMg != null ? String(data.phosphorusMg) + 'mg' : '-'
				this.postData.nutritionStats = [
					{ label: '热量(kcal)', value: energy },
					{ label: '蛋白质', value: protein },
					{ label: '钾', value: potassium },
					{ label: '磷', value: phosphorus }
				]
				uni.showToast({ title: '已补充营养估算', icon: 'success' })
			} catch (e) {
				console.warn('AI 营养估算失败:', e)
				uni.showToast({ title: '估算失败，请重试', icon: 'none' })
			} finally {
				this.aiNutritionFilling = false
			}
		},

		// 格式化帖子数据
		formatPostData(data) {
			// 解析图片
			let images = []
			if (data.imagesJson) {
				try {
					images = typeof data.imagesJson === 'string' 
						? JSON.parse(data.imagesJson) 
						: data.imagesJson
				} catch (e) {
					images = []
				}
			}
			if (data.coverImage && !images.includes(data.coverImage)) {
				images.unshift(data.coverImage)
			}
			
			// 解析标签
			let tags = []
			if (data.tagsJson) {
				try {
					const parsedTags = typeof data.tagsJson === 'string' 
						? JSON.parse(data.tagsJson) 
						: data.tagsJson
					tags = parsedTags.map(tag => {
						if (typeof tag === 'string') {
							return tag.startsWith('#') ? tag : '#' + tag
						}
						return tag.name ? '#' + tag.name : ''
					}).filter(t => t)
				} catch (e) {
					tags = []
				}
			}
			
			// 如果没有标签，从内容中提取关键字
			if (tags.length === 0 && data.content) {
				const keywordMatch = data.content.match(/关键字[：:]\s*([^<\n]+)/i)
				if (keywordMatch && keywordMatch[1]) {
					const keywords = keywordMatch[1].split(/[,，、]/).map(k => k.trim()).filter(k => k)
					tags = keywords.slice(0, 4).map(k => '#' + k)
				}
			}
			
			// 解析营养数据：支持多种后端字段名，以及从打卡数据计算
			let nutritionStats = this.buildNutritionStatsFromDetailData(data)
			
			// 提取纯文本内容
			let description = ''
			if (data.content) {
				description = this.stripHtml(data.content)
				// 移除关键字和简介标记
				description = description
					.replace(/关键字[：:][^简介]*/i, '')
					.replace(/简介[：:]/i, '')
					.trim()
			}
			
			this.postData = {
				id: data.id || data.postId,
				images: images.length > 0 ? images : [],
				mealType: data.mealType || '分享',
				title: data.title || '',
				score: data.score || 0,
				description: description,
				tags: tags,
				author: {
					id: data.userId,
					avatar: data.userAvatar || '👤',
					name: data.userName || '匿名用户',
					time: this.formatTime(data.createdAt)
				},
				nutritionStats: nutritionStats,
				aiComment: data.aiComment || '',
				comments: [],
				likeCount: data.likeCount || 0,
				favoriteCount: data.collectCount || 0,
				commentCount: data.commentCount || 0,
				checkInRecordId: data.checkInRecordId,
				videoUrl: data.videoUrl || null,
				videoStatus: data.videoStatus,
				hasVideo: data.hasVideo || false
			}
		},
		
		// 移除HTML标签
		stripHtml(html) {
			if (!html) return ''
			return html
				.replace(/<br\s*\/?>/gi, '\n')
				.replace(/<hr\s*\/?>/gi, '\n')
				.replace(/<[^>]+>/g, '')
				.replace(/&nbsp;/g, ' ')
				.replace(/&lt;/g, '<')
				.replace(/&gt;/g, '>')
				.replace(/&amp;/g, '&')
				.replace(/&quot;/g, '"')
				.replace(/&#39;/g, "'")
				.replace(/\s+/g, ' ')
				.trim()
		},
		
		// 格式化时间
		formatTime(timeStr) {
			if (!timeStr) return ''
			
			const date = new Date(timeStr.replace(/-/g, '/'))
			const now = new Date()
			const diff = now - date
			
			const minute = 60 * 1000
			const hour = 60 * minute
			const day = 24 * hour
			
			if (diff < minute) {
				return '刚刚'
			} else if (diff < hour) {
				return Math.floor(diff / minute) + '分钟前'
			} else if (diff < day) {
				return Math.floor(diff / hour) + '小时前'
			} else if (diff < 7 * day) {
				return Math.floor(diff / day) + '天前'
			} else {
				const month = date.getMonth() + 1
				const dayOfMonth = date.getDate()
				return `${month}月${dayOfMonth}日`
			}
		},
		
		// 加载评论列表
		async loadComments() {
			if (this.isLoadingComments || !this.hasMoreComments) return
			
			this.isLoadingComments = true
			
			try {
				const res = await getCommentList(this.postId, {
					page: this.commentPage,
					limit: this.commentLimit
				})
				
				const list = res.data?.list || res.data || []
				const formattedComments = list.map(item => ({
					id: item.id,
					avatar: item.userAvatar || '👤',
					name: item.userName || '匿名用户',
					time: this.formatTime(item.createdAt),
					text: item.content,
					likeCount: item.likeCount || 0,
					isLiked: item.isLiked || false,
					userId: item.userId
				}))
				
				if (this.commentPage === 1) {
					this.postData.comments = formattedComments
				} else {
					this.postData.comments = [...this.postData.comments, ...formattedComments]
				}
				
				this.hasMoreComments = list.length >= this.commentLimit
				
			} catch (error) {
				console.error('加载评论失败:', error)
			} finally {
				this.isLoadingComments = false
			}
		},
		
		// 加载相关推荐
		async loadRelatedPosts() {
			try {
				const res = await getCommunityList({
					tab: 'recommend',
					page: 1,
					limit: 4
				})
				
				const list = res.data?.list || res.data || []
				this.relatedPosts = list
					.filter(item => item.id !== this.postData.id)
					.slice(0, 2)
					.map(item => {
						let coverImage = item.coverImage || ''
						if (!coverImage && item.imagesJson) {
							try {
								const images = typeof item.imagesJson === 'string' 
									? JSON.parse(item.imagesJson) 
									: item.imagesJson
								coverImage = images[0] || ''
							} catch (e) {}
						}
						return {
							id: item.id || item.postId,
							image: coverImage,
							title: item.title
						}
					})
			} catch (error) {
				console.error('加载相关推荐失败:', error)
			}
		},
		
		onImageChange(e) {
			this.currentImageIndex = e.detail.current
		},
		
		// 关注/取消关注
		async toggleFollow() {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			const newFollowState = !this.isFollowed
			this.isFollowed = newFollowState
			
			try {
				await apiToggleFollow(this.postData.author.id, newFollowState)
				uni.showToast({
					title: newFollowState ? '已关注' : '取消关注',
					icon: 'none'
				})
			} catch (error) {
				this.isFollowed = !newFollowState
				uni.showToast({
					title: '操作失败，请重试',
					icon: 'none'
				})
			}
		},
		
		// 一键借鉴打卡
		handleCopyCheckin() {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			const recordId = this.postData.checkInRecordId || this.postData.id
			uni.navigateTo({
				url: `/pages/tool/checkin-publish?sourcePostId=${this.postData.id}&sourceType=learn`
			})
		},
		
		// 评论点赞
		async toggleCommentLike(comment, index) {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			const newLikeState = !comment.isLiked
			const newLikeCount = newLikeState ? comment.likeCount + 1 : comment.likeCount - 1
			
			// 乐观更新UI
			this.$set(this.postData.comments, index, {
				...comment,
				isLiked: newLikeState,
				likeCount: newLikeCount
			})
			
			// 调用评论点赞API（复用帖子点赞接口，传入评论ID）
			try {
				await apiToggleLike(comment.id, newLikeState)
			} catch (error) {
				// 回滚
				this.$set(this.postData.comments, index, {
					...comment,
					isLiked: !newLikeState,
					likeCount: comment.likeCount
				})
				uni.showToast({
					title: '操作失败，请重试',
					icon: 'none'
				})
			}
		},
		
		// 帖子点赞
		async toggleLike() {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			const postIdNum = typeof this.postId === 'number' ? this.postId : parseInt(this.postId, 10)
			if (!postIdNum || isNaN(postIdNum)) {
				console.error('[post-detail] toggleLike: invalid postId', this.postId)
				uni.showToast({ title: '操作失败，请重试', icon: 'none' })
				return
			}
			
			const newLikeState = !this.isLiked
			const newLikeCount = newLikeState 
				? this.postData.likeCount + 1 
				: this.postData.likeCount - 1
			
			// 乐观更新
			this.isLiked = newLikeState
			this.postData.likeCount = newLikeCount
			
			try {
				await apiToggleLike(postIdNum, newLikeState)
			} catch (error) {
				console.error('[post-detail] toggleLike failed:', error)
				// 回滚
				this.isLiked = !newLikeState
				this.postData.likeCount = newLikeState 
					? newLikeCount - 1 
					: newLikeCount + 1
				uni.showToast({
					title: '操作失败，请重试',
					icon: 'none'
				})
			}
		},
		
		// 收藏
		async toggleFavorite() {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			const postIdNum = typeof this.postId === 'number' ? this.postId : parseInt(this.postId, 10)
			if (!postIdNum || isNaN(postIdNum)) {
				console.error('[post-detail] toggleFavorite: invalid postId', this.postId)
				uni.showToast({ title: '操作失败，请重试', icon: 'none' })
				return
			}
			
			const newCollectState = !this.isCollected
			const newCollectCount = newCollectState 
				? this.postData.favoriteCount + 1 
				: this.postData.favoriteCount - 1
			
			// 乐观更新
			this.isCollected = newCollectState
			this.postData.favoriteCount = newCollectCount
			
			try {
				await toggleCollect(postIdNum, newCollectState)
				uni.showToast({
					title: newCollectState ? '已收藏' : '取消收藏',
					icon: 'none'
				})
			} catch (error) {
				console.error('[post-detail] toggleFavorite failed:', error)
				// 回滚
				this.isCollected = !newCollectState
				this.postData.favoriteCount = newCollectState 
					? newCollectCount - 1 
					: newCollectCount + 1
				uni.showToast({
					title: '操作失败，请重试',
					icon: 'none'
				})
			}
		},
		
		handleShare() {
			uni.showShareMenu({
				withShareTicket: true
			})
		},
		
		// 点击评论输入框
		focusInput() {
			if (!checkLogin()) {
				uni.showToast({ title: '请先登录', icon: 'none' })
				setTimeout(() => toLogin(), 1000)
				return
			}
			
			// 显示评论输入弹窗
			uni.showModal({
				title: '发表评论',
				editable: true,
				placeholderText: '说点什么...',
				success: async (res) => {
					if (res.confirm && res.content) {
						await this.submitComment(res.content)
					}
				}
			})
		},
		
		// 提交评论
		async submitComment(content) {
			if (!content.trim()) {
				uni.showToast({ title: '请输入评论内容', icon: 'none' })
				return
			}
			
			uni.showLoading({ title: '发送中...' })
			
			try {
				await addComment({
					postId: this.postId,
					content: content.trim()
				})
				
				uni.hideLoading()
				uni.showToast({ title: '评论成功', icon: 'success' })
				
				// 刷新评论列表
				this.commentPage = 1
				this.hasMoreComments = true
				this.loadComments()
				
				// 更新评论数
				this.postData.commentCount++
				
			} catch (error) {
				uni.hideLoading()
				uni.showToast({
					title: error.message || '评论失败，请重试',
					icon: 'none'
				})
			}
		},
		
		previewImage(index) {
			if (this.postData.images && this.postData.images.length > 0) {
				uni.previewImage({
					current: index,
					urls: this.postData.images
				})
			}
		},
		
		getMealIcon(type) {
			const map = {
				'早餐': '🌅',
				'午餐': '☀️',
				'晚餐': '🌙',
				'加餐': '🍪',
				'breakfast': '🌅',
				'lunch': '☀️',
				'dinner': '🌙',
				'snack': '🍪'
			}
			return map[type] || '🍽️'
		},
		
		goToRelatedPost(item) {
			uni.navigateTo({
				url: `/pages/tool/post-detail?id=${item.id}`
			})
		},
		
		// 格式化数量显示
		formatCount(count) {
			if (!count) return '0'
			if (count >= 10000) {
				return (count / 10000).toFixed(1) + 'w'
			} else if (count >= 1000) {
				return (count / 1000).toFixed(1) + 'k'
			}
			return String(count)
		}
	}
}
</script>

<style lang="scss" scoped>
.post-detail-page {
	min-height: 100vh;
	background: linear-gradient(180deg, #fafafa 0%, #ffffff 100%);
	display: flex;
	flex-direction: column;
}

/* 内容滚动区域 */
.content-scroll {
	flex: 1;
	margin-bottom: 120rpx;
}

/* 视频播放器区域 */
.video-player-section {
	width: 100%;
	height: 750rpx;
	position: relative;
	background: #000000;

	.video-player {
		width: 100%;
		height: 100%;
	}

	.meal-tag {
		position: absolute;
		left: 32rpx;
		top: 32rpx;
		background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
		border: 1rpx solid rgba(255, 255, 255, 0.8);
		border-radius: 50rpx;
		padding: 8rpx 16rpx;
		display: flex;
		align-items: center;
		gap: 12rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.3);
		z-index: 10;

		.meal-icon {
			font-size: 32rpx;
		}

		.meal-text {
			font-size: 28rpx;
			color: #3e5481;
		}
	}
}

/* 图片轮播区域 */
.image-carousel {
	width: 100%;
	height: 750rpx;
	position: relative;
	background: #f4f5f7;

	.swiper {
		width: 100%;
		height: 100%;
	}

	.carousel-image {
		width: 100%;
		height: 100%;
	}

	.meal-tag {
		position: absolute;
		left: 32rpx;
		top: 32rpx;
		background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
		border: 1rpx solid rgba(255, 255, 255, 0.8);
		border-radius: 50rpx;
		padding: 8rpx 16rpx;
		display: flex;
		align-items: center;
		gap: 12rpx;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);

		.meal-icon {
			font-size: 32rpx;
		}

		.meal-text {
			font-size: 28rpx;
			color: #3e5481;
		}
	}

	.image-counter {
		position: absolute;
		right: 32rpx;
		bottom: 32rpx;
		background: rgba(0, 0, 0, 0.7);
		border-radius: 50rpx;
		padding: 8rpx 16rpx;
		font-size: 24rpx;
		color: #ffffff;
		box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
	}
}

/* 帖子内容区域 */
.post-content-section {
	padding: 32rpx;
	background: #ffffff;
}

.title-row {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 24rpx;
	margin-bottom: 24rpx;

	.post-title {
		flex: 1;
		font-size: 36rpx;
		color: #2e3e5c;
		line-height: 1.4;
		font-weight: 400;
	}

	.score-badge {
		background: linear-gradient(135deg, #ff8c5a 0%, #ff6b35 50%, #e85a2a 100%);
		border-radius: 50rpx;
		padding: 8rpx 20rpx;
		font-size: 28rpx;
		color: #ffffff;
		white-space: nowrap;
	}
}

.post-description {
	font-size: 28rpx;
	color: #3e5481;
	line-height: 1.6;
	margin-bottom: 32rpx;
	white-space: pre-wrap;
}

.tag-list {
	display: flex;
	flex-wrap: wrap;
	gap: 16rpx;
	margin-bottom: 32rpx;
}

.tag-item {
	background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%);
	border: 1rpx solid rgba(255, 136, 68, 0.3);
	border-radius: 50rpx;
	padding: 8rpx 24rpx;
	font-size: 24rpx;
	color: #ff7722;
	box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.1);
}

.author-section {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding-top: 32rpx;
	border-top: 1rpx solid #d0dbea;
}

.author-info {
	display: flex;
	align-items: center;
	gap: 24rpx;
}

.author-avatar {
	width: 80rpx;
	height: 80rpx;
	background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%);
	border: 2rpx solid #ff7722;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;

	.avatar-icon {
		font-size: 36rpx;
	}
}

.author-details {
	display: flex;
	flex-direction: column;
	gap: 8rpx;

	.author-name {
		font-size: 28rpx;
		color: #2e3e5c;
	}

	.post-time {
		font-size: 24rpx;
		color: #9fa5c0;
	}
}

.follow-btn {
	background: linear-gradient(135deg, #ff8c5a 0%, #ff6b35 100%);
	border-radius: 50rpx;
	padding: 16rpx 32rpx;
	box-shadow: 0 8rpx 24rpx rgba(255, 107, 53, 0.3);

	text {
		font-size: 28rpx;
		color: #ffffff;
		font-weight: 500;
	}
}

/* 营养统计卡片 */
.nutrition-stats-card {
	margin: 10rpx 32rpx;
	padding: 32rpx;
	background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 50%, #ffffff 100%);
	border: 2rpx solid rgba(255, 136, 68, 0.3);
	border-radius: 32rpx;
	box-shadow: 0 16rpx 60rpx rgba(255, 136, 68, 0.15);
}

.stats-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin-bottom: 24rpx;
}

.stats-title {
	display: flex;
	align-items: center;
	gap: 16rpx;

	.title-icon {
		width: 48rpx;
		height: 48rpx;
		background: linear-gradient(135deg, #ff9966 0%, #ff8844 100%);
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 24rpx;
		box-shadow: 0 8rpx 12rpx rgba(0, 0, 0, 0.1);
	}

	.title-text {
		font-size: 28rpx;
		color: #2e3e5c;
	}
}

.stats-unit {
	background: rgba(255, 255, 255, 0.9);
	border: 1rpx solid rgba(255, 136, 68, 0.3);
	border-radius: 50rpx;
	padding: 8rpx 20rpx;
	font-size: 24rpx;
	color: #ff7722;
}

.stats-grid {
	display: flex;
	gap: 24rpx;
}

.stat-item {
	flex: 1;
	background: rgba(255, 255, 255, 0.8);
	border: 1rpx solid rgba(255, 136, 68, 0.2);
	border-radius: 24rpx;
	padding: 20rpx;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8rpx;

	.stat-value {
		font-size: 32rpx;
		color: #2e3e5c;
		font-weight: 500;
	}

	.stat-label {
		font-size: 24rpx;
		color: #9fa5c0;
		text-align: center;
	}
}

/* AI营养师点评 */
.ai-comment-card {
	margin: 32rpx;
	padding: 32rpx;
	background: #ffffff;
	border: 1rpx solid #d0dbea;
	border-radius: 24rpx;
}

.ai-header {
	display: flex;
	gap: 24rpx;
}

.ai-avatar {
	width: 72rpx;
	height: 72rpx;
	background: #ff6b35;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 24rpx;
	color: #ffffff;
	flex-shrink: 0;
}

.ai-info {
	flex: 1;
}

.ai-name-row {
	display: flex;
	align-items: center;
	gap: 16rpx;
	margin-bottom: 16rpx;

	.ai-name {
		font-size: 28rpx;
		color: #2e3e5c;
	}

	.ai-verified {
		font-size: 24rpx;
		color: #9fa5c0;
	}
}

.ai-comment-text {
	font-size: 28rpx;
	color: #3e5481;
	line-height: 1.6;
}

/* 一键借鉴打卡按钮 */
.copy-checkin-btn {
	margin: 22rpx;
	height: 94rpx;
	background: linear-gradient(135deg, #ff8844 0%, #ff6611 50%, #ff7722 100%);
	border-radius: 24rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16rpx;
	box-shadow: 0 16rpx 60rpx rgba(255, 107, 53, 0.3);

	.btn-icon {
		font-size: 36rpx;
	}

	.btn-text {
		font-size: 28rpx;
		color: #ffffff;
		font-weight: 500;
	}
}

/* 分隔线 */
.divider {
	height: 16rpx;
	background: #f4f5f7;
}

/* 评论区域 */
.comments-section {
	padding: 32rpx;
	background: #ffffff;
}

.comments-header {
	display: flex;
	align-items: center;
	gap: 16rpx;
	margin-bottom: 32rpx;

	.comments-icon {
		width: 48rpx;
		height: 48rpx;
		background: linear-gradient(135deg, #ff9966 0%, #ff8844 100%);
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 24rpx;
		box-shadow: 0 8rpx 12rpx rgba(0, 0, 0, 0.1);
	}

	.comments-title {
		font-size: 28rpx;
		color: #2e3e5c;
	}
}

.comments-list {
	display: flex;
	flex-direction: column;
	gap: 32rpx;
}

.comment-item {
	display: flex;
	gap: 24rpx;
}

.comment-avatar {
	width: 72rpx;
	height: 72rpx;
	background: linear-gradient(135deg, #fff5f0 0%, #ffe8dc 100%);
	border: 1rpx solid rgba(255, 136, 68, 0.3);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 32rpx;
	flex-shrink: 0;
}

.comment-content {
	flex: 1;
}

.comment-header {
	display: flex;
	align-items: center;
	gap: 16rpx;
	margin-bottom: 16rpx;

	.comment-name {
		font-size: 28rpx;
		color: #2e3e5c;
	}

	.comment-time {
		font-size: 24rpx;
		color: #9fa5c0;
	}
}

.comment-text {
	font-size: 28rpx;
	color: #3e5481;
	line-height: 1.6;
	margin-bottom: 16rpx;
}

.comment-actions {
	display: flex;
	align-items: center;
	gap: 8rpx;
}

.like-btn {
	display: flex;
	align-items: center;
	gap: 8rpx;

	.like-icon {
		font-size: 28rpx;
	}

	.like-count {
		font-size: 24rpx;
		color: #9fa5c0;
	}
}

/* 相关推荐 */
.related-section {
	padding: 32rpx;
	background: linear-gradient(180deg, #fafafa 0%, #f4f5f7 100%);
}

.related-header {
	display: flex;
	align-items: center;
	gap: 16rpx;
	margin-bottom: 32rpx;

	.related-icon {
		width: 48rpx;
		height: 48rpx;
		background: linear-gradient(135deg, #ff8c5a 0%, #ff6b35 100%);
		border-radius: 50%;
		display: flex;
		align-items: center;
		justify-content: center;
		font-size: 24rpx;
		box-shadow: 0 8rpx 12rpx rgba(0, 0, 0, 0.1);
	}

	.related-title {
		font-size: 28rpx;
		color: #2e3e5c;
	}
}

.related-list {
	display: flex;
	gap: 24rpx;
}

.related-item {
	flex: 1;
	height: 440rpx;
	background: #ffffff;
	border: 1rpx solid #d0dbea;
	border-radius: 32rpx;
	overflow: hidden;

	.related-image {
		width: 100%;
		height: 100%;
	}
}

/* 底部安全距离 */
.safe-bottom {
	height: 40rpx;
}

/* 底部操作栏 */
.bottom-bar {
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	height: 120rpx;
	background: rgba(255, 255, 255, 0.95);
	border-top: 1rpx solid rgba(0, 0, 0, 0.1);
	padding: 0 32rpx;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 24rpx;
	z-index: 1000;
}

.input-box {
	flex: 1;
	height: 72rpx;
	background: #f4f5f7;
	border-radius: 50rpx;
	padding: 0 32rpx;
	display: flex;
	align-items: center;

	.input-placeholder {
		font-size: 28rpx;
		color: #9fa5c0;
	}
}

.action-buttons {
	display: flex;
	gap: 24rpx;
	align-items: center;
}

.action-btn-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4rpx;

	.action-icon {
		font-size: 40rpx;
	}

	.action-count {
		font-size: 24rpx;
		color: #9fa5c0;
	}
}
</style>

