<template>
	<div v-if="items" class="tui-comment-list">
		<div class="comment" v-for="comment in items" :key="comment.id">
			<!-- 主评论 -->
			<div class="user">
				<!-- 主评论头像 -->
				<template v-if="comment.user">
					<a
						:href="`/user/space/${comment.userId}`"
						target="_blank"
						v-popup:config="popupUserStore.config"
						@mouseenter="popupUserStore.user.value = comment.user"
					>
						<img
							class="avatar"
							:class="(<any>ImageType)[comment.user.profile.avatarType]"
							:src="UserAPI.getAvatarURL(comment.user.profile)"
							alt="主评论头像"
						/>
					</a>
					<a
						class="name pink selectable"
						:href="`/user/space/${comment.userId}`"
						v-text="comment.user.name"
						v-popup:config="popupUserStore.config"
						@mouseenter="popupUserStore.user.value = comment.user"
					></a>
				</template>
				<!-- 游客的 -->
				<template v-else>
					<img class="avatar ir-pixelated" :src="defAvatarURL" alt="头像" />
					<div class="name gray selectable clip-text" v-text="comment.nick"></div>
				</template>
			</div>
			<div class="content">
				<!-- 主评论内容 -->
				<markdown-view class="value" :content="comment.content" />
				<div class="reply-to">
					<a class="button" href="javascript:" @click="replyTo(comment)">回复</a>
					<span
						class="light-gray"
						v-text="Time.toPassedDate(comment.createdAt)"
						v-popup:text="Time.toDateTime(comment.createdAt)"
					></span>
				</div>
				<!-- 子评论 -->
				<comment-reply-list :comment="comment" @reply="replyTo" />
				<t-pagination
					class="pages"
					v-if="6 < comment.repliesLength"
					:total="comment.repliesLength"
					:pageSize="6"
					:showPageSize="false"
					v-model:current="comment.repliesCurrent"
					@change="() => doFetchReply(comment)"
				>
					<template #total-content>
						<div class="total" v-text="`共 ${comment.repliesLength} 条回复`"></div>
					</template>
				</t-pagination>
				<!-- 回复表单，此表单跟随（页面上）激活的回复对象 -->
				<comment-reply-form
					v-if="canReply && comment.id && activeReply === comment.id"
					:commentId="comment.id"
					:replyId="replyId"
					:replyToNick="replyToNick"
					@submit="onSubmitReply"
					@cancel="activeReply = -1"
				/>
			</div>
		</div>
	</div>
</template>

<script lang="ts" setup>
import {
	CommentAPI,
	CommentReply,
	CommentReplyView,
	CommentView,
	CommonAPI,
	ImageType,
	MarkdownView,
	SettingKey,
	SettingMapper,
	Time,
	UserAPI
} from "timi-web";
import { CommentReplyForm, CommentReplyList } from "~/components";
import { popupUserStore } from "timi-tdesign-pc";

defineOptions({
	name: "CommentList"
});

const props = withDefaults(defineProps<{
	items: CommentView[],
	canReply?: boolean,
}>(), {
	canReply: true
});
const { items, canReply } = toRefs(props);

// 默认头像
const defAvatarURL = ref();
onMounted(async () => {
	const res = JSON.parse(SettingMapper.getValue(SettingKey.PUBLIC_RESOURCES) as string);
	defAvatarURL.value = CommonAPI.getAttachmentReadAPI(res.user.avatar);
});

// 激活的回复评论下标
const activeReply = ref();
const replyId = ref();
// 被回复昵称
const replyToNick = ref();

/**
 * 获取回复
 *
 * @param comment 所属评论
 */
async function doFetchReply(comment: CommentView) {
	// 组件下标以 1 开始，分页参数以 0 开始
	comment.repliesPage.index = comment.repliesCurrent - 1;
	const result = await CommentAPI.pageReply(comment.repliesPage);
	comment.replies.length = 0;
	comment.replies.push(...result.list);
}

/**
 * 触发回复表单（表单会跟随评论）
 *
 * @param comment 跟随的评论
 * @param replyTo 被回复对象
 */
async function replyTo(comment: CommentView, replyTo?: CommentReplyView) {
	activeReply.value = comment.id;
	if (replyTo) {
		// 被回复对象
		replyToNick.value = replyTo.sender?.name || replyTo.senderNick;
		replyId.value = replyTo.id;
	} else {
		replyToNick.value = comment.user?.name || comment.nick;
	}
}

function onSubmitReply(reply: CommentReply) {
	activeReply.value = -1;

	const comment = items.value.find(comment => comment.id === reply.commentId)!;
	comment.repliesLength++;
	comment.repliesCurrent = Math.ceil(comment.repliesLength / 6); // 上取整最后一页
	doFetchReply(comment);
}
</script>

<style lang="less" scoped>
.tui-comment-list {
	font-size: 13px;
	line-height: 1.5;

	.comment {
		display: flex;
		line-height: 1.5;
		border-bottom: 2px solid #CDDEF0;

		.user {
			width: 120px;
			padding: 16px 0;
			text-align: center;
			background: #E4EFFA;
			transition: .5s var(--tui-bezier);

			.avatar {
				width: 64px;
				border: 1px solid #FBC7D4;
				margin: 0 auto 10px auto;
				padding: 3px;
				background: #FFF;
				transition: .5s var(--tui-bezier);
			}
		}

		.content {
			width: calc(100% - 120px);
			transition: .5s var(--tui-bezier);

			.value {
				width: calc(100% - 2rem);
				padding: .5rem;
				min-height: 92px;
			}

			.pages {
				padding: 4px 4px 4px 1rem;
				border-top: 1px solid #E4EFFA;

				.total {
					flex: 1;
				}
			}

			.reply-to {
				display: flex;
				padding-right: .5rem;
				justify-content: end;

				> a {
					margin-right: .5rem;
				}
			}
		}
	}
}

@media screen and (max-width: 650px) {
	.tui-comment-list {

		.comment {

			.user {
				width: 60px;
				padding: 8px 0;
				transition: .5s var(--tui-bezier);

				.avatar {
					width: 32px;
					margin: 0 auto 4px auto;
					padding: 2px;
					transition: .5s var(--tui-bezier);
				}
			}

			.content {
				width: calc(100% - 60px);
				transition: .5s var(--tui-bezier);
			}
		}
	}
}
</style>
