<template>
	<view class="dcp-root">
		<scroll-view
			v-if="rows.length > 0"
			class="dcp-list"
			scroll-y
			:show-scrollbar="false"
		>
			<view
				v-for="(item, index) in rows"
				:key="(item && item.id) || index"
				class="dcp-row"
			>
				<image
					class="dcp-avatar"
					:src="avatarSrc(item && item.user && item.user.avatar)"
					@tap.stop="onUser(item)"
				/>
				<view class="dcp-body">
					<view class="dcp-head">
						<view class="dcp-head-left">
							<view v-if="index === 0" class="dcp-rank dcp-rank-1">
								<text class="dcp-rank-text">第一</text>
							</view>
							<view v-else-if="index === 1" class="dcp-rank dcp-rank-2">
								<text class="dcp-rank-text">第二</text>
							</view>
							<view v-else-if="index === 2" class="dcp-rank dcp-rank-3">
								<text class="dcp-rank-text">第三</text>
							</view>
							<text class="dcp-nick">{{ (item.user && item.user.nickname) || '游客' }}</text>
						</view>
						<view class="dcp-like" @tap.stop="onLike(index)">
							<text :class="item.hasLike ? 'dcp-like-num dcp-like-num-on' : 'dcp-like-num'">{{ item.like || 0 }}</text>
							<text :class="item.hasLike ? 'dcp-like-icon dcp-like-icon-on' : 'dcp-like-icon'">{{ item.hasLike ? '♥' : '♡' }}</text>
						</view>
					</view>
					<text class="dcp-content">{{ plain(item.content) }}</text>
					<view class="dcp-meta">
						<text class="dcp-time">{{ item.createtime_text || '' }}</text>
						<view
							class="dcp-action"
							@tap.stop="onReply(item.user && item.user.nickname, item.id)"
						>
							<text class="dcp-action-reply">回复</text>
						</view>
						<view v-if="item.owner" class="dcp-action" @tap.stop="onDelete(index)">
							<text class="dcp-action-del">删除</text>
						</view>
					</view>
					<view v-if="item.childlist && item.childlist.length > 0" class="dcp-sublist">
						<view
							v-for="(child, k) in item.childlist"
							:key="(child && child.id) || k"
							class="dcp-row dcp-row-sub"
						>
							<image
								class="dcp-avatar dcp-avatar-sub"
								:src="avatarSrc(child && child.user && child.user.avatar)"
								@tap.stop="onUser(child)"
							/>
							<view class="dcp-body">
								<view class="dcp-head">
									<view class="dcp-head-left">
										<text class="dcp-nick dcp-nick-sub">{{ (child.user && child.user.nickname) || '游客' }}</text>
									</view>
									<view class="dcp-like" @tap.stop="onLike(index, k)">
										<text :class="child.hasLike ? 'dcp-like-num dcp-like-num-on' : 'dcp-like-num'">{{ child.like || 0 }}</text>
										<text :class="child.hasLike ? 'dcp-like-icon dcp-like-icon-on' : 'dcp-like-icon'">{{ child.hasLike ? '♥' : '♡' }}</text>
									</view>
								</view>
								<text class="dcp-content dcp-content-sub">{{ plain(child.content) }}</text>
								<view class="dcp-meta">
									<text class="dcp-time">{{ child.createtime_text || '' }}</text>
									<view
										class="dcp-action"
										@tap.stop="onReply(child.user && child.user.nickname, item.id)"
									>
										<text class="dcp-action-reply">回复</text>
									</view>
									<view v-if="child.owner" class="dcp-action" @tap.stop="onDelete(index, k)">
										<text class="dcp-action-del">删除</text>
									</view>
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</scroll-view>

		<view v-else class="dcp-empty">
			<text class="dcp-empty-title">暂无评论，</text>
			<text class="dcp-empty-cta" @tap.stop="focusInput">来写第一条 →</text>
		</view>

		<view class="dcp-inputbar" :style="inputBarStyle" @tap.stop>
			<input
				ref="commentInput"
				class="dcp-input"
				v-model="form.content"
				:placeholder="placeholder"
				placeholder-style="color: #b0b4c0;"
				:maxlength="200"
				confirm-type="send"
				@confirm="onSubmit"
			/>
			<view class="dcp-send" @tap.stop="onSubmit">
				<text class="dcp-send-text">发送</text>
			</view>
		</view>
	</view>
</template>

<script>
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: 'DetailCommentPanel',
	props: {
		findId: { type: [Number, String], default: 0 },
		list: { type: Array, default: () => [] },
		count: { type: Number, default: 0 },
		safeBottomInset: { type: Number, default: 0 }
	},
	data() {
		return {
			rows: [],
			form: { pid: null, content: '' },
			safeBottom: 0
		}
	},
	computed: {
		signedIn() {
			return !!(this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.isLogin)
		},
		placeholder() {
			return this.form.pid ? '回复评论…' : '说点什么～'
		},
		inputBarStyle() {
			const safeB = this.safeBottom || 0
			return safeB > 0 ? { paddingBottom: `${safeB}px` } : {}
		}
	},
	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
	},
	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)
		},
		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) {
				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
			}
		},
		onReply(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) {
				uni.showToast({ title: (err && err.message) || '发送失败', icon: 'none' })
			}
		},
		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, list: this.rows.slice() })
					} catch (err) {
						uni.showToast({ title: (err && err.message) || '删除失败', icon: 'none' })
					}
				}
			})
		}
	}
}
</script>

<style scoped>
.dcp-root {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
	height: 100%;
	background-color: #ffffff;
}
.dcp-list {
	flex: 1;
	min-height: 0;
	padding: 0 28rpx;
	box-sizing: border-box;
}
.dcp-row {
	display: flex;
	flex-direction: row;
	padding-top: 20rpx;
	padding-bottom: 20rpx;
}
.dcp-row-sub {
	padding-top: 14rpx;
	padding-bottom: 14rpx;
}
.dcp-avatar {
	width: 70rpx;
	height: 70rpx;
	border-radius: 50%;
	background-color: #eef2f8;
	margin-right: 20rpx;
	flex-shrink: 0;
}
.dcp-avatar-sub {
	width: 60rpx;
	height: 60rpx;
	margin-right: 16rpx;
}
.dcp-body {
	flex: 1;
	min-width: 0;
}
.dcp-head {
	display: flex;
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
}
.dcp-head-left {
	display: flex;
	flex-direction: row;
	align-items: center;
	flex: 1;
	min-width: 0;
}
.dcp-rank {
	height: 32rpx;
	padding: 0 10rpx;
	border-radius: 10rpx;
	margin-right: 12rpx;
	display: flex;
	align-items: center;
	justify-content: center;
}
.dcp-rank-1 { background-color: #ff8c1a; }
.dcp-rank-2 { background-color: #aaaa00; }
.dcp-rank-3 { background-color: #2b6cb0; }
.dcp-rank-text {
	color: #ffffff;
	font-size: 20rpx;
	line-height: 28rpx;
}
.dcp-nick {
	color: #5c6070;
	font-size: 28rpx;
	font-weight: 500;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: 350rpx;
}
.dcp-nick-sub {
	font-size: 26rpx;
}
.dcp-like {
	display: flex;
	flex-direction: row;
	align-items: center;
	padding-left: 16rpx;
	height: 50rpx;
}
.dcp-like-num {
	color: #8a8d9e;
	font-size: 24rpx;
	margin-right: 8rpx;
}
.dcp-like-num-on {
	color: #ff4d6a;
}
.dcp-like-icon {
	color: #8a8d9e;
	font-size: 28rpx;
}
.dcp-like-icon-on {
	color: #ff4d6a;
}
.dcp-content {
	color: #1a1d26;
	font-size: 28rpx;
	line-height: 40rpx;
	margin-top: 6rpx;
	margin-bottom: 8rpx;
}
.dcp-content-sub {
	font-size: 26rpx;
	line-height: 36rpx;
}
.dcp-meta {
	display: flex;
	flex-direction: row;
	align-items: center;
	margin-bottom: 4rpx;
}
.dcp-time {
	color: #b0b4c0;
	font-size: 22rpx;
	margin-right: 20rpx;
}
.dcp-action {
	margin-right: 20rpx;
	padding: 4rpx 0;
}
.dcp-action-reply {
	color: #4a8cff;
	font-size: 22rpx;
}
.dcp-action-del {
	color: #ff4d6a;
	font-size: 22rpx;
}
.dcp-sublist {
	background-color: #f5f7fb;
	border-radius: 12rpx;
	padding: 6rpx 16rpx;
	margin-top: 12rpx;
}
.dcp-empty {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}
.dcp-empty-title {
	color: #8a8d9e;
	font-size: 26rpx;
}
.dcp-empty-cta {
	color: #4a8cff;
	font-size: 26rpx;
	margin-top: 8rpx;
	padding: 8rpx 16rpx;
}
.dcp-inputbar {
	flex-shrink: 0;
	display: flex;
	flex-direction: row;
	align-items: center;
	padding: 16rpx 24rpx;
	border-top: 1rpx solid rgba(0, 0, 0, 0.06);
	background-color: #ffffff;
	box-sizing: border-box;
}
.dcp-input {
	flex: 1;
	height: 70rpx;
	background-color: #f5f7fb;
	color: #1a1d26;
	border-radius: 35rpx;
	padding: 0 28rpx;
	font-size: 28rpx;
}
.dcp-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;
}
.dcp-send-text {
	color: #ffffff;
	font-size: 26rpx;
	font-weight: 500;
}
</style>
