<template>
	<view class="ct-root">
		<!-- 评论列表 -->
		<scroll-view
			v-if="rows.length > 0"
			class="ct-list"
			:style="{ height: listHeight + 'px' }"
			scroll-y
		>
			<view
				v-for="(item, index) in rows"
				:key="(item && item.id) || index"
				class="ct-row"
			>
				<image
					class="ct-avatar"
					:src="avatarSrc(item && item.user && item.user.avatar)"
					@click.stop="onUser(item)"
				/>
				<view class="ct-body">
					<!-- 父评论：昵称 + 点赞 -->
					<view class="ct-head">
						<view class="ct-head-left">
							<view v-if="index === 0" class="ct-rank ct-rank-1">
								<text class="ct-rank-text">第一</text>
							</view>
							<view v-else-if="index === 1" class="ct-rank ct-rank-2">
								<text class="ct-rank-text">第二</text>
							</view>
							<view v-else-if="index === 2" class="ct-rank ct-rank-3">
								<text class="ct-rank-text">第三</text>
							</view>
							<text class="ct-nick">{{ (item.user && item.user.nickname) || '游客' }}</text>
						</view>
						<view class="ct-like" @click.stop="onLike(index)">
							<text :class="item.hasLike ? 'ct-like-num ct-like-num-on' : 'ct-like-num'">{{ item.like || 0 }}</text>
							<text :class="item.hasLike ? 'ct-like-icon ct-like-icon-on' : 'ct-like-icon'">{{ item.hasLike ? '♥' : '♡' }}</text>
						</view>
					</view>

					<!-- 父评论：内容 -->
					<text class="ct-content">{{ plain(item.content) }}</text>

					<!-- 父评论：时间 + 回复 + 删除 -->
					<view class="ct-meta">
						<text class="ct-time">{{ item.createtime_text || '' }}</text>
						<view
							class="ct-action"
							@click.stop="onReply(item.user && item.user.nickname, item.user && item.user.nickname, item.id)"
						>
							<text class="ct-action-reply">回复</text>
						</view>
						<view v-if="item.owner" class="ct-action" @click.stop="onDelete(index)">
							<text class="ct-action-del">删除</text>
						</view>
					</view>

					<!-- 子评论列表 -->
					<view v-if="item.childlist && item.childlist.length > 0" class="ct-sublist">
						<view
							v-for="(child, k) in item.childlist"
							:key="(child && child.id) || k"
							class="ct-row ct-row-sub"
						>
							<image
								class="ct-avatar ct-avatar-sub"
								:src="avatarSrc(child && child.user && child.user.avatar)"
								@click.stop="onUser(child)"
							/>
							<view class="ct-body">
								<view class="ct-head">
									<view class="ct-head-left">
										<text class="ct-nick ct-nick-sub">{{ (child.user && child.user.nickname) || '游客' }}</text>
									</view>
									<view class="ct-like" @click.stop="onLike(index, k)">
										<text :class="child.hasLike ? 'ct-like-num ct-like-num-on' : 'ct-like-num'">{{ child.like || 0 }}</text>
										<text :class="child.hasLike ? 'ct-like-icon ct-like-icon-on' : 'ct-like-icon'">{{ child.hasLike ? '♥' : '♡' }}</text>
									</view>
								</view>
								<text class="ct-content ct-content-sub">{{ plain(child.content) }}</text>
								<view class="ct-meta">
									<text class="ct-time">{{ child.createtime_text || '' }}</text>
									<view
										class="ct-action"
										@click.stop="onReply(item.user && item.user.nickname, child.user && child.user.nickname, item.id)"
									>
										<text class="ct-action-reply">回复</text>
									</view>
									<view v-if="child.owner" class="ct-action" @click.stop="onDelete(index, k)">
										<text class="ct-action-del">删除</text>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</scroll-view>

		<!-- 空状态 -->
		<view v-else class="ct-empty" :style="{ height: listHeight + 'px' }">
			<text class="ct-empty-title">暂无评论，</text>
			<text class="ct-empty-cta" @click.stop="focusInput">来写第一条 →</text>
		</view>

		<!-- 底部输入栏：fixed + 键盘跟随（照搬 HKLive comment-nvue.vue） -->
		<view class="ct-inputbar" :style="inputBarStyle" @click.stop>
			<input
				ref="commentInput"
				class="ct-input"
				v-model="form.content"
				:placeholder="placeholder"
				placeholder-style="color: #999;"
				:maxlength="200"
				adjust-position="false"
				:cursor-spacing="0"
				confirm-type="send"
				@blur="onInputBlur"
				@confirm="onSubmit"
			/>
			<view class="ct-send" @click.stop="onSubmit">
				<text class="ct-send-text">发送</text>
			</view>
		</view>
		<view :style="{ height: spacerHeight + 'px' }" />
	</view>
</template>

<script>
/**
 * 视频评论弹层主体
 *
 * 移植自参考工程 HKLive\components\comment\comment-nvue.vue，做了精简：
 *   - 移除 i18n（直接中文文案）
 *   - 移除举报跳转（NewHKLive 暂无 complaint 路由）
 *   - 移除 $appKit / $wanlshop 等私有插件依赖
 *   - 头像加载用 NewHKLive 的 buildOssUrl
 *   - 接口走 features/feed/feed-gateway.js 的封装
 *
 * 接口：
 *   - 列表已由父组件传入 props.list（父组件用 fetchClipComments 拉好）
 *   - 点赞 / 回复 / 删除 / 新增 自行调用 gateway
 *
 * Events:
 *   - complete  { type: 'add' | 'del', count: number }
 *                父组件用来同步外层 likes/comments 计数
 */
import { stripHtml } from '@/features/feed/clip-normalize'
import { buildOssUrl } from '@/core/media/oss-url'
import {
	addClipComment,
	deleteClipComment,
	fetchClipComments,
	toggleClipCommentLike
} from '@/features/feed/feed-gateway'
import { openUserProfile } from '@/core/nav/navigation'

export default {
	name: 'CommentThread',
	props: {
		findId: { type: [Number, String], default: 0 },
		list: { type: Array, default: () => [] },
		count: { type: Number, default: 0 },
		listHeight: { type: Number, default: 400 },
		safeBottomInset: { type: Number, default: 0 },
		tabbarHeight: { type: Number, default: 0 }
	},
	data() {
		return {
			rows: [],
			form: { pid: null, content: '' },
			keyboardHeight: 0,
			safeBottom: 0,
			inputRowPx: 0,
			inputInnerPx: 0,
			inputBarPadV: 0,
			inputBottomFineTune: 0,
			_kbHandler: null,
			_kbClearTimer: null
		}
	},
	computed: {
		signedIn() {
			return !!this.$store.state.user.isLogin
		},
		placeholder() {
			return this.form.pid ? '回复评论…' : '说点什么～'
		},
		/** 照搬 HKLive comment-nvue.vue#inputBarStyle，键盘弹起时再下移 inputBottomFineTune */
		inputBarStyle() {
			const tabH = this.tabbarHeight || 0
			const safeB = this.safeBottom || 0
			const kb = this.keyboardHeight > 0 ? this.keyboardHeight : 0
			const fine = this.inputBottomFineTune || 0
			const inner = this.inputInnerPx || uni.upx2px(70)
			const padV = this.inputBarPadV || uni.upx2px(16)
			const padH = uni.upx2px(24)
			const barH = inner + padV * 2
			if (kb > 0) {
				const lift = Math.max(0, kb - tabH - fine)
				return {
					height: `${barH}px`,
					paddingTop: `${padV}px`,
					paddingBottom: `${padV}px`,
					paddingLeft: `${padH}px`,
					paddingRight: `${padH}px`,
					bottom: `${lift}px`
				}
			}
			return {
				height: `${barH + safeB}px`,
				paddingTop: `${padV}px`,
				paddingBottom: `${safeB + padV}px`,
				paddingLeft: `${padH}px`,
				paddingRight: `${padH}px`,
				bottom: `${tabH}px`
			}
		},
		spacerHeight() {
			if (this.keyboardHeight > 0) return 0
			const inner = this.inputInnerPx || uni.upx2px(70)
			const padV = this.inputBarPadV || uni.upx2px(16)
			return inner + padV * 2 + (this.safeBottom || 0) + (this.tabbarHeight || 0) + 8
		}
	},
	watch: {
		list: {
			immediate: true,
			handler(next) {
				this.rows = Array.isArray(next) ? next.slice() : []
			}
		}
	},
	mounted() {
		const sys = uni.getSystemInfoSync() || {}
		const sysSafe = (sys.safeAreaInsets && sys.safeAreaInsets.bottom) || 0
		this.safeBottom = (this.safeBottomInset && this.safeBottomInset > 0) ? this.safeBottomInset : sysSafe
		this.inputInnerPx = uni.upx2px(70)
		this.inputBarPadV = uni.upx2px(16)
		this.inputRowPx = this.inputInnerPx + this.inputBarPadV * 2
		this.inputBottomFineTune = uni.upx2px(60)
		if (uni.onKeyboardHeightChange) {
			this._kbHandler = (res) => {
				this.keyboardHeight = (res && res.height) || 0
			}
			uni.onKeyboardHeightChange(this._kbHandler)
		}
	},
	beforeDestroy() {
		if (this._kbClearTimer) clearTimeout(this._kbClearTimer)
		if (this._kbHandler && uni.offKeyboardHeightChange) {
			uni.offKeyboardHeightChange(this._kbHandler)
			this._kbHandler = null
		}
	},
	methods: {
		plain(content) {
			return stripHtml(content || '')
		},
		avatarSrc(path) {
			return buildOssUrl(path, 80, 80, 2, 'avatar')
		},
		requireSignIn() {
			if (this.signedIn) return true
			uni.showModal({
				title: '请先登录',
				content: '登录后才能评论、点赞',
				confirmText: '去登录',
				cancelText: '取消',
				success: ({ confirm }) => {
					if (confirm) uni.navigateTo({ url: '/pages/passport/lobby' })
				}
			})
			return false
		},
		onUser(row) {
			openUserProfile(row)
		},

		/**
		 * 评论 / 子评论点赞 toggle
		 * @param {number} index 父评论索引
		 * @param {number|null} childKey 子评论索引；null 表示对父评论操作
		 */
		async onLike(index, childKey = null) {
			if (!this.requireSignIn()) return
			const parent = this.rows[index]
			if (!parent) return
			const target = childKey == null ? parent : (parent.childlist && parent.childlist[childKey])
			if (!target || !target.id) return
			if (target._busy) return
			target._busy = true

			const was = !!target.hasLike
			const next = !was
			this.$set(target, 'hasLike', next)
			this.$set(target, 'like', Math.max(0, Number(target.like || 0) + (next ? 1 : -1)))

			try {
				const flag = await toggleClipCommentLike(target.id)
				if (flag === 1 || flag === 0) {
					const serverOn = flag === 1
					if (serverOn !== next) {
						this.$set(target, 'hasLike', serverOn)
						this.$set(target, 'like', Math.max(0, Number(target.like || 0) + (serverOn ? 0 : -2) /* 抵消乐观更新 */))
					}
				}
			} catch (err) {
				console.warn('[comment] like failed, rolling back', err)
				this.$set(target, 'hasLike', was)
				this.$set(target, 'like', Math.max(0, Number(target.like || 0) + (was ? 1 : -1)))
				uni.showToast({ title: (err && err.message) || '点赞失败', icon: 'none' })
			} finally {
				target._busy = false
			}
		},

		/**
		 * 点 "回复" 时：把输入框预填 "@昵称 "、设置 pid 为父评论 id、聚焦
		 */
		onReply(_pUserNick, reUserNick, pid) {
			if (!this.requireSignIn()) return
			this.form.pid = pid
			this.form.content = reUserNick ? `@${reUserNick} ` : ''
			this.focusInput()
		},

		focusInput() {
			this.$nextTick(() => {
				try {
					this.$refs.commentInput && this.$refs.commentInput.focus && this.$refs.commentInput.focus()
				} catch (_) {}
			})
		},

		clearForm() {
			this.form.pid = null
			this.form.content = ''
		},
		async reloadComments() {
			if (!this.findId) return this.count || 0
			const result = await fetchClipComments(this.findId)
			this.rows = Array.isArray(result.list) ? result.list.slice() : []
			return Number(result.count) || this.rows.length || 0
		},
		/**
		 * 提交评论 / 回复
		 */
		async onSubmit() {
			if (!this.requireSignIn()) return
			const content = (this.form.content || '').trim()
			if (content.length < 2) {
				uni.showToast({ title: '内容太短', icon: 'none' })
				return
			}
			try {
				await addClipComment(this.findId, content, this.form.pid)
				uni.showToast({ title: '已发送', icon: 'none' })
				this.clearForm()
				const nextCount = await this.reloadComments()
				this.$emit('complete', { type: 'add', count: nextCount, list: this.rows.slice() })
			} catch (err) {
				console.warn('[comment] add failed', err)
				uni.showToast({ title: (err && err.message) || '发送失败', icon: 'none' })
			}
		},

		/**
		 * 删除评论（含确认弹框）
		 * @param {number} index 父评论索引
		 * @param {number|null} childKey 子评论索引；null 表示删除父评论
		 */
		async onDelete(index, childKey = null) {
			if (!this.requireSignIn()) return
			uni.showModal({
				title: '删除评论',
				content: '删除后无法恢复，将同时删除其下所有回复。',
				confirmText: '确认',
				cancelText: '取消',
				success: async ({ confirm }) => {
					if (!confirm) return
					const parent = this.rows[index]
					if (!parent) return
					const target = childKey == null ? parent : (parent.childlist && parent.childlist[childKey])
					if (!target || !target.id) return
					try {
						const result = await deleteClipComment(target.id, target.find_id || this.findId)
						if (childKey == null) {
							this.rows.splice(index, 1)
						} else {
							parent.childlist.splice(childKey, 1)
						}
						const nextCount = result && result.count != null ? result.count : Math.max(0, (this.count || 0) - 1)
						this.$emit('complete', { type: 'del', count: nextCount })
					} catch (err) {
						console.warn('[comment] delete failed', err)
						uni.showToast({ title: (err && err.message) || '删除失败', icon: 'none' })
					}
				}
			})
		},

		onInputBlur() {
			if (this._kbClearTimer) clearTimeout(this._kbClearTimer)
			this._kbClearTimer = setTimeout(() => {
				this.keyboardHeight = 0
			}, 180)
		}
	}
}
</script>

<style scoped>
.ct-root {
	background-color: transparent;
}
.ct-list {
	padding: 0 28rpx;
	box-sizing: border-box;
}

.ct-row {
	display: flex;
	flex-direction: row;
	padding-top: 20rpx;
	padding-bottom: 20rpx;
}
.ct-row-sub {
	padding-top: 14rpx;
	padding-bottom: 14rpx;
}

.ct-avatar {
	width: 70rpx;
	height: 70rpx;
	border-radius: 50%;
	background-color: rgba(255, 255, 255, 0.08);
	margin-right: 20rpx;
	flex-shrink: 0;
}
.ct-avatar-sub {
	width: 60rpx;
	height: 60rpx;
	margin-right: 16rpx;
}

.ct-body {
	flex: 1;
	min-width: 0;
}

.ct-head {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
}
.ct-head-left {
	display: flex;
	flex-direction: row;
	align-items: center;
	flex: 1;
	min-width: 0;
}

.ct-rank {
	height: 32rpx;
	padding: 0 10rpx;
	border-radius: 10rpx;
	margin-right: 12rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}
.ct-rank-1 { background-color: #ff8c1a; }
.ct-rank-2 { background-color: #aaaa00; }
.ct-rank-3 { background-color: #2b6cb0; }
.ct-rank-text {
	color: #ffffff;
	font-size: 20rpx;
	line-height: 28rpx;
}

.ct-nick {
	color: rgba(255, 255, 255, 0.66);
	font-size: 28rpx;
	font-weight: 500;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: 350rpx;
}
.ct-nick-sub {
	font-size: 26rpx;
}

.ct-like {
	display: flex;
	flex-direction: row;
	align-items: center;
	padding-left: 16rpx;
	padding-right: 0;
	height: 50rpx;
}
.ct-like-num {
	color: rgba(255, 255, 255, 0.66);
	font-size: 24rpx;
	margin-right: 8rpx;
}
.ct-like-num-on {
	color: #ff4d6a;
}
.ct-like-icon {
	color: rgba(255, 255, 255, 0.66);
	font-size: 28rpx;
}
.ct-like-icon-on {
	color: #ff4d6a;
}

.ct-content {
	color: rgba(255, 255, 255, 0.9);
	font-size: 28rpx;
	line-height: 40rpx;
	margin-top: 6rpx;
	margin-bottom: 8rpx;
}
.ct-content-sub {
	font-size: 26rpx;
	line-height: 36rpx;
}

.ct-meta {
	display: flex;
	flex-direction: row;
	align-items: center;
	margin-bottom: 4rpx;
}
.ct-time {
	color: rgba(255, 255, 255, 0.5);
	font-size: 22rpx;
	margin-right: 20rpx;
}
.ct-action {
	margin-right: 20rpx;
	padding: 4rpx 0;
}
.ct-action-reply {
	color: #4a8cff;
	font-size: 22rpx;
}
.ct-action-del {
	color: #ff4d6a;
	font-size: 22rpx;
}

.ct-sublist {
	background-color: rgba(255, 255, 255, 0.04);
	border-radius: 12rpx;
	padding: 6rpx 16rpx;
	margin-top: 12rpx;
}

.ct-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}
.ct-empty-title {
	color: rgba(255, 255, 255, 0.45);
	font-size: 26rpx;
}
.ct-empty-cta {
	color: #4a8cff;
	font-size: 26rpx;
	margin-top: 8rpx;
	padding: 8rpx 16rpx;
}

.ct-inputbar {
	position: fixed;
	left: 0;
	right: 0;
	z-index: 100;
	background-color: #1a1a1a;
	border-top: 1rpx solid rgba(255, 255, 255, 0.08);
	display: flex;
	flex-direction: row;
	align-items: center;
	box-sizing: border-box;
}
.ct-input {
	flex: 1;
	height: 70rpx;
	background-color: rgba(255, 255, 255, 0.08);
	color: #ffffff;
	border-radius: 35rpx;
	padding: 0 28rpx;
	font-size: 28rpx;
}
.ct-send {
	height: 70rpx;
	background-color: #4a8cff;
	border-radius: 35rpx;
	padding: 0 32rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-left: 20rpx;
	flex-shrink: 0;
}
.ct-send-text {
	color: #ffffff;
	font-size: 26rpx;
	font-weight: 500;
}
</style>
