<template>
	<view class="detail-page">
		<view class="nav" :style="{ paddingTop: statusBarTop + 'px' }">
			<view class="back" @tap="back"><uni-icons type="left" size="24" color="#18372f"></uni-icons></view>
			<view class="nav-title">{{post && post.postType === 'partner' ? '搭子详情' : '校园墙详情'}}</view>
			<view class="nav-right"></view>
		</view>
		<scroll-view scroll-y class="content-scroll" :style="{ paddingTop: navHeight + 'px' }" @scrolltolower="loadMoreComments">
			<view class="card post-card" v-if="post">
				<view class="author-row">
					<image class="avatar" :src="displayAvatar(post)" mode="aspectFill"></image>
					<view class="author-main">
						<view class="author">{{displayName(post)}}<text>已实名</text></view>
						<view class="meta">{{post.createTime || ''}} · {{post.regionName || '本校'}}</view>
					</view>
				</view>
				<view class="title">{{post.title}}</view>
				<view class="content">{{post.contentText || stripHtml(post.content)}}</view>
				<view v-if="imageList.length" class="image-grid" :class="'image-grid--' + Math.min(imageList.length, 3)">
					<image
						v-for="(pic,index) in imageList"
						:key="pic"
						:src="pic"
						:mode="imageList.length === 1 ? 'aspectFit' : 'aspectFill'"
						:style="getPostImageStyle(pic, imageList.length)"
						@load="onPostImageLoad(pic, $event)"
						@tap="previewImages(index)"
					></image>
				</view>
				<view class="tag-row" v-if="tagList.length">
					<text v-for="tag in tagList" :key="tag">{{tag}}</text>
				</view>
				<view class="partner-box" v-if="post.postType === 'partner'">
					<view><text>地点</text>{{post.location || '可商量'}}</view>
					<view><text>时间</text>{{post.activityTime || '可商量'}}</view>
					<view><text>人数</text>{{post.joinedCount || 0}}/{{post.targetCount || '不限'}}</view>
				</view>
				<view class="contact-box" v-if="hasContact">
					<view v-if="post.contactWechat"><text>微信</text>{{post.contactWechat}}</view>
					<view v-if="post.contactPhone"><text>手机</text>{{post.contactPhone}}</view>
				</view>
				<view class="stats">{{post.likeCount || 0}} 赞 · {{post.commentCount || 0}} 评论 · 热度 {{post.hotScore || 0}}</view>
			</view>

			<view class="card comment-card">
				<view class="section-head">
					<text>评论 {{commentsTotal}}</text>
					<view @tap="focusComment">我要评论</view>
				</view>
				<view class="comment-item" v-for="item in comments" :key="item.id">
					<image class="comment-avatar" :src="displayAvatar(item)" mode="aspectFill"></image>
					<view class="comment-main">
						<view class="comment-name">{{displayName(item)}}</view>
						<view class="comment-content">{{item.content}}</view>
						<view class="reply-list" v-if="item.replies && item.replies.length">
							<view class="reply-item" v-for="reply in item.replies" :key="reply.id">
								<text>{{displayName(reply)}}</text>
								<text v-if="reply.replyToUserName"> 回复 {{reply.replyToUserName}}</text>
								：{{reply.content}}
							</view>
						</view>
						<view class="comment-actions">
							<text>{{item.createTime || ''}}</text>
							<text class="comment-action-text" @tap="replyComment(item)">回复</text>
							<text class="comment-action-text" @tap="reportComment(item)">举报</text>
							<text class="comment-action-text" v-if="item.userId == currentUserId" @tap="deleteComment(item)">删除</text>
						</view>
					</view>
				</view>
				<view class="empty" v-if="!comments.length">还没有评论，快来聊聊</view>
				<view class="load-state">{{commentLoading ? '评论加载中...' : (commentHasMore ? '上滑加载更多评论' : '评论到底了')}}</view>
			</view>
			<view class="bottom-space"></view>
		</scroll-view>

		<uni-popup ref="commentPopup" type="center" background-color="transparent">
			<view class="comment-popup">
				<view class="popup-title">{{replyTarget.id ? '回复评论' : '发表评论'}}</view>
				<view class="popup-desc">评论内容会进行审核，请友善交流</view>
				<textarea v-model.trim="commentText" maxlength="200" :placeholder="replyTarget.id ? '回复 ' + (replyTarget.userName || '校园同学') : '说点什么...'" />
				<view class="anonymous-comment-row">
					<text>匿名评论</text>
					<switch :checked="commentAnonymous" color="#34c7a2" @change="toggleCommentAnonymous" />
				</view>
				<view class="popup-actions">
					<view @tap="closeCommentPopup">取消</view>
					<view :class="{ disabled: commentSubmitting }" @tap="submitComment">{{commentSubmitting ? '发送中' : '发送'}}</view>
				</view>
			</view>
		</uni-popup>

		<view class="bottom-bar" v-if="post">
			<view class="bar-action" @tap="focusComment"><uni-icons type="chat" size="22" color="#59706a"></uni-icons><text>评论</text></view>
			<view class="bar-action" @tap="likePost"><uni-icons :type="post.liked ? 'heart-filled' : 'heart'" size="22" :color="post.liked ? '#ff6868' : '#59706a'"></uni-icons><text>点赞</text></view>
			<view class="bar-action" @tap="reportPost"><uni-icons type="flag" size="22" color="#59706a"></uni-icons><text>举报</text></view>
			<view class="chat-btn" v-if="canUsePartnerChat" @tap="goChat">搭一下</view>
		</view>
		<ie-auth-dialog />
	</view>
</template>

<script>
	import {
		getCampusPostDetail,
		toggleCampusLike,
		addCampusComment,
		pageCampusComments,
		deleteCampusComment,
		submitCampusComplaint,
		createCampusChatSession
	} from '@/common/campusApi.js'
	import { getIeProfile } from '@/common/ieApi.js'
	import { ensureIeVerifiedBeforeAction } from '@/common/ieRealNameAuth.js'
	import IeAuthDialog from '@/package1/components/ie-auth-dialog/ie-auth-dialog.vue'

	export default {
		components: { IeAuthDialog },
		data() {
			return {
				id: '',
				post: null,
				statusBarTop: 24,
				comments: [],
				commentsTotal: 0,
				commentPageNum: 1,
				commentPageSize: 10,
				commentTotalPages: 1,
				commentLoading: false,
				commentText: '',
				commentSubmitting: false,
				commentAnonymous: false,
				replyTarget: {},
				currentUserId: String(uni.getStorageSync('id') || ''),
				defaultAvatar: '/static/images/img/songshu.png',
				likeLocked: false,
				imageSizeMap: {}
			}
		},
		computed: {
			navHeight() { return this.statusBarTop + uni.upx2px(104) },
			imageList() { return this.post && this.post.imageList ? this.post.imageList : [] },
			tagList() { return this.post && this.post.tagList ? this.post.tagList : [] },
			commentHasMore() { return this.commentPageNum < this.commentTotalPages },
			hasContact() { return !!(this.post && (this.post.contactWechat || this.post.contactPhone)) },
			canUsePartnerChat() {
				return false
			}
		},
		onLoad(options = {}) {
			this.id = options.id || ''
			if (uni.getMenuButtonBoundingClientRect) this.statusBarTop = uni.getMenuButtonBoundingClientRect().top || this.statusBarTop
			this.loadDetail()
			this.loadComments(true)
		},
		methods: {
			back() { uni.navigateBack() },
			loadDetail() {
				getCampusPostDetail(this.id).then(post => {
					this.post = post
				})
			},
			loadComments(reset) {
				if (this.commentLoading) return
				if (reset) {
					this.commentPageNum = 1
					this.commentTotalPages = 1
				}
				this.commentLoading = true
				pageCampusComments(this.id, this.commentPageNum, this.commentPageSize).then(page => {
					const records = page && (page.records || page.content) ? (page.records || page.content) : []
					this.commentTotalPages = Number(page && (page.pages || page.totalPages)) || 1
					this.commentsTotal = Number(page && (page.total || page.totalElements)) || records.length
					this.comments = reset ? records : this.comments.concat(records)
					uni.$emit('campusUnreadChange')
				}).finally(() => {
					this.commentLoading = false
				})
			},
			loadMoreComments() {
				if (this.commentLoading || !this.commentHasMore) return
				this.commentPageNum += 1
				this.loadComments(false)
			},
			previewImages(index) {
				uni.previewImage({ urls: this.imageList, current: this.imageList[index] || this.imageList[0] })
			},
			onPostImageLoad(pic, e) {
				if (!pic || !e || !e.detail) return
				this.$set(this.imageSizeMap, this.getImageKey(pic), {
					width: Number(e.detail.width) || 0,
					height: Number(e.detail.height) || 0
				})
			},
			getImageKey(pic) {
				const value = String(pic || '')
				let hash = 0
				for (let i = 0; i < value.length; i++) {
					hash = ((hash << 5) - hash) + value.charCodeAt(i)
					hash |= 0
				}
				return 'img_' + Math.abs(hash)
			},
			getPostImageStyle(pic, count) {
				if (count > 1) return ''
				const maxWidth = 640
				const maxHeight = 520
				const size = this.imageSizeMap[this.getImageKey(pic)]
				if (!size || !size.width || !size.height) {
					return 'width:' + maxWidth + 'rpx;height:360rpx;max-width:' + maxWidth + 'rpx;max-height:' + maxHeight + 'rpx;'
				}
				const ratio = size.width / size.height
				let width = maxWidth
				let height = Math.round(width / ratio)
				if (height > maxHeight) {
					height = maxHeight
					width = Math.round(height * ratio)
				}
				return 'width:' + width + 'rpx;height:' + height + 'rpx;max-width:' + maxWidth + 'rpx;max-height:' + maxHeight + 'rpx;'
			},
			displayName(item) {
				return item && item.userName ? item.userName : '半径同学'
			},
			displayAvatar(item) {
				return item && item.userAvatar ? item.userAvatar : this.defaultAvatar
			},
			stripHtml(html = '') { return String(html).replace(/<[^>]+>/g, '') },
			async ensureVerified(actionText) {
				const profile = await getIeProfile().catch(() => null)
				return ensureIeVerifiedBeforeAction({
					profile: profile || {},
					actionText,
					authDialog: { badge: '校园圈', title: '实名认证', desc: actionText + '前需完成实名认证' },
					reload: getIeProfile
				})
			},
			async focusComment() {
				const ok = await this.ensureVerified('评论校园圈内容')
				if (!ok) return
				this.replyTarget = {}
				this.commentText = ''
				this.commentAnonymous = false
				this.$refs.commentPopup.open()
			},
			async replyComment(item) {
				const ok = await this.ensureVerified('评论校园圈内容')
				if (!ok) return
				this.replyTarget = item || {}
				this.commentText = ''
				this.commentAnonymous = false
				this.$refs.commentPopup.open()
			},
			toggleCommentAnonymous(e) {
				this.commentAnonymous = !!(e && e.detail && e.detail.value)
			},
			closeCommentPopup() {
				this.$refs.commentPopup.close()
			},
			async submitComment() {
				if (this.commentSubmitting) return
				if (!this.commentText) {
					uni.showToast({ title: '请输入评论内容', icon: 'none' })
					return
				}
				const ok = await this.ensureVerified('评论校园圈内容')
				if (!ok) return
				this.commentSubmitting = true
				try {
					const comment = await addCampusComment({
						postId: this.id,
						...this.getSubmitCommentProfile(),
						parentId: this.replyTarget.parentId ? this.replyTarget.parentId : this.replyTarget.id,
						replyToUserId: this.replyTarget.userId,
						replyToUserName: this.replyTarget.userName,
						content: this.commentText
					})
					if (!this.isCommentSubmitSuccess(comment)) {
						this.showCommentSubmitFail(comment)
						return
					}
					this.closeCommentPopup()
					this.commentText = ''
					this.replyTarget = {}
					this.loadDetail()
					this.loadComments(true)
				} catch (e) {
					this.showCommentSubmitFail(e)
				} finally {
					this.commentSubmitting = false
				}
			},
			isCommentSubmitSuccess(comment) {
				if (!comment) return false
				if (comment.success === false) return false
				if (comment.code !== undefined && Number(comment.code) !== 200) return false
				return !!(comment.id || comment.content || comment.createTime)
			},
			showCommentSubmitFail(error) {
				const message = (error && (error.message || error.msg)) || '评论内容审核未通过，请修改后重试'
				uni.showToast({ title: message, icon: 'none', duration: 2200 })
			},
			deleteComment(item) {
				uni.showModal({
					title: '删除评论',
					content: '确认删除这条评论吗？',
					success: res => {
						if (!res.confirm) return
						deleteCampusComment(item.id).then(() => this.loadComments(true))
					}
				})
			},
			likePost() {
				if (this.likeLocked) return
				this.likeLocked = true
				toggleCampusLike({ targetType: 'post', targetId: this.id }).then(res => {
					if (!res) return
					this.post.liked = !!res.liked
					this.post.likeCount = Number(res.count) || 0
				}).finally(() => {
					setTimeout(() => { this.likeLocked = false }, 800)
				})
			},
			reportPost() {
				this.submitReport({ complaintType: 'post', postId: this.id })
			},
			reportComment(item) {
				this.submitReport({ complaintType: 'comment', postId: this.id, commentId: item.id })
			},
			submitReport(payload) {
				uni.showModal({
					title: '举报',
					editable: true,
					placeholderText: '请填写举报原因',
					success: res => {
						if (!res.confirm) return
						const reason = (res.content || '').trim()
						if (!reason) {
							uni.showToast({ title: '请填写举报原因', icon: 'none' })
							return
						}
						submitCampusComplaint({ ...payload, reason }).then(() => {
							uni.showToast({ title: '举报已提交', icon: 'success' })
						})
					}
				})
			},
			async goChat() {
				if (!this.canUsePartnerChat) return
				const ok = await this.ensureVerified('联系校园圈搭子')
				if (!ok) return
				createCampusChatSession(this.id).then(session => {
					if (!session || !session.sessionId) return
					uni.navigateTo({ url: '/package1/campus/campusChat?sessionId=' + session.sessionId })
				})
			},
			getSubmitCommentProfile() {
				if (this.commentAnonymous) {
					return {
						userName: '半径同学',
						userAvatar: ''
					}
				}
				return {
					userName: uni.getStorageSync('nickName') || uni.getStorageSync('nickname') || uni.getStorageSync('userName') || '',
					userAvatar: uni.getStorageSync('avatar') || uni.getStorageSync('avatarUrl') || uni.getStorageSync('headimgurl') || ''
				}
			}
		}
	}
</script>

<style scoped>
	.detail-page { min-height: 100vh; background: #f6faf8; }
	.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 10; display: flex; align-items: center; justify-content: space-between; padding: 16rpx 24rpx; background: rgba(246,250,248,.96); }
	.back, .nav-right { width: 64rpx; height: 64rpx; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; }
	.nav-title { font-size: 32rpx; font-weight: 800; color: #18372f; }
	.content-scroll { height: 100vh; box-sizing: border-box; }
	.card { margin: 20rpx 24rpx; padding: 26rpx; background: #fff; border-radius: 30rpx; box-shadow: 0 12rpx 32rpx rgba(38, 76, 69, .08); }
	.author-row { display: flex; align-items: center; }
	.avatar, .comment-avatar { width: 64rpx; height: 64rpx; border-radius: 50%; background: #dff8f0; color: #257c69; text-align: center; line-height: 64rpx; font-weight: 700; }
	.author-main { flex: 1; margin-left: 14rpx; }
	.author { font-size: 27rpx; font-weight: 700; color: #263d38; }
	.author text { margin-left: 10rpx; padding: 4rpx 10rpx; border-radius: 999rpx; background: #e9faf5; color: #23a987; font-size: 20rpx; }
	.meta, .stats { margin-top: 8rpx; color: #8b9995; font-size: 23rpx; }
	.title { margin-top: 24rpx; color: #172d28; font-size: 36rpx; font-weight: 800; }
	.content { margin-top: 16rpx; color: #4d625d; font-size: 28rpx; line-height: 1.7; }
	.image-grid { display: grid; gap: 10rpx; margin-top: 18rpx; }
	.image-grid--1 { display: flex; align-items: center; justify-content: flex-start; max-width: 640rpx; max-height: 520rpx; overflow: hidden; border-radius: 20rpx; background: transparent; }
	.image-grid--2 { grid-template-columns: repeat(2, 1fr); }
	.image-grid--3 { grid-template-columns: repeat(3, 1fr); }
	.image-grid image { width: 100%; height: 210rpx; max-width: 100%; border-radius: 20rpx; background: #eef5f3; }
	.image-grid--1 image { max-width: 640rpx; max-height: 520rpx; background: transparent; }
	.tag-row { display: flex; flex-wrap: wrap; gap: 10rpx; margin-top: 18rpx; }
	.tag-row text { padding: 8rpx 16rpx; border-radius: 999rpx; background: #eefaf6; color: #2f9a81; font-size: 22rpx; }
	.partner-box { margin-top: 20rpx; display: grid; gap: 12rpx; }
	.partner-box view { background: #f6faf8; border-radius: 18rpx; padding: 16rpx; color: #344a45; font-size: 25rpx; }
	.partner-box text { color: #8a9994; margin-right: 16rpx; }
	.contact-box { margin-top: 18rpx; display: grid; gap: 12rpx; }
	.contact-box view { padding: 16rpx; border-radius: 18rpx; background: #f0fbf7; color: #256d5f; font-size: 25rpx; }
	.contact-box text { color: #8a9994; margin-right: 16rpx; }
	.section-head { display: flex; justify-content: space-between; font-size: 30rpx; font-weight: 800; color: #1d352f; }
	.section-head view { color: #22a786; font-size: 24rpx; }
	.comment-item { display: flex; padding: 24rpx 0; border-bottom: 1rpx solid #eef3f1; }
	.comment-main { flex: 1; margin-left: 16rpx; min-width: 0; }
	.comment-name { font-size: 25rpx; font-weight: 700; color: #263d38; }
	.comment-content { margin-top: 8rpx; color: #435852; font-size: 26rpx; line-height: 1.5; }
	.reply-list { margin-top: 12rpx; padding: 14rpx; background: #f7faf9; border-radius: 18rpx; color: #4d625d; font-size: 24rpx; }
	.reply-item { margin-bottom: 8rpx; }
	.reply-item text { color: #1b9278; }
	.comment-actions { display: flex; align-items: center; gap: 24rpx; margin-top: 12rpx; color: #8a9994; font-size: 22rpx; }
	.comment-action-text { color: #263d38; font-size: 26rpx; font-weight: 900; }
	.empty, .load-state { text-align: center; color: #8a9692; padding: 26rpx 0; font-size: 24rpx; }
	.bottom-space { height: 160rpx; }
	.bottom-bar { position: fixed; left: 0; right: 0; bottom: 0; padding: 16rpx 24rpx 32rpx; display: flex; align-items: center; justify-content: flex-end; gap: 16rpx; background: rgba(255,255,255,.96); box-shadow: 0 -8rpx 28rpx rgba(31, 67, 59, .08); }
	.bar-action { width: 96rpx; display: flex; flex-direction: column; align-items: center; color: #59706a; font-size: 21rpx; }
	.chat-btn { flex: 1; height: 82rpx; line-height: 82rpx; text-align: center; border-radius: 999rpx; background: #34c7a2; color: #fff; font-weight: 800; }
	.comment-popup { width: 620rpx; padding: 30rpx; border-radius: 30rpx; background: #fff; }
	.popup-title { font-size: 30rpx; font-weight: 800; color: #18372f; }
	.popup-desc { margin-top: 8rpx; color: #81918c; font-size: 23rpx; }
	.comment-popup textarea { margin-top: 18rpx; width: 100%; height: 190rpx; box-sizing: border-box; background: #f6faf8; border-radius: 20rpx; padding: 18rpx; font-size: 26rpx; }
	.anonymous-comment-row { margin-top: 18rpx; display: flex; align-items: center; justify-content: space-between; color: #526761; font-size: 25rpx; }
	.popup-actions { display: flex; justify-content: flex-end; gap: 18rpx; margin-top: 20rpx; }
	.popup-actions view { padding: 14rpx 28rpx; border-radius: 999rpx; background: #eef3f1; color: #526761; }
	.popup-actions view:last-child { background: #34c7a2; color: #fff; }
	.popup-actions .disabled { opacity: .6; }
</style>
