<template>
	<div
		class="cl-chat-session"
		:class="{
			'is-position': browser.isMini,
			'is-show': sessionVisible
		}"
	>
		<!-- 关键字搜索 -->
		<div class="cl-chat-session__search">
			<el-input
				v-model="keyWord"
				placeholder="搜索"
				prefix-icon="el-icon-search"
				size="small"
				clearable
				@clear="onSearch"
				@keyup.enter="onSearch"
			/>
		</div>

		<!-- 会话列表 -->
		<ul v-loading="loading" class="cl-chat-session__list scroller1">
			<li
				v-for="(item, index) in list"
				:key="index"
				class="cl-chat-session__item"
				:class="{
					'is-active': session ? item.id == session.id : false
				}"
				@click="toDetail(item)"
				@contextmenu.stop.prevent="openCM($event, item.id, Number(index))"
			>
				<!-- 头像 -->
				<div class="avatar">
					<el-badge
						:value="item.serviceUnreadCount"
						:hidden="item.serviceUnreadCount === 0"
						:max="99"
					>
						<img :src="item.headimgurl" alt="" />
					</el-badge>
				</div>

				<!-- 昵称，内容 -->
				<div class="det">
					<p class="name">{{ item.nickname }}</p>
					<p class="content">{{ item.lastMessage }}</p>
				</div>
			</li>
		</ul>
	</div>
</template>

<script lang="ts">
import { computed, defineComponent, inject, onUnmounted, reactive, ref } from "vue";
import { useStore } from "vuex";
import { ElMessage } from "element-plus";
import { isEmpty } from "/@/core/utils";
import { ContextMenu } from "/$/crud";
import { parseContent } from "../utils";

export default defineComponent({
	setup() {
		const store = useStore();
		const service = inject<any>("service");
		const mitt = inject<any>("mitt");

		// 当前会话信息
		const session = computed(() => store.getters.session);
		// 是否显示会话列表
		const sessionVisible = computed(() => store.getters.sessionVisible);
		// 浏览器信息
		const browser = computed(() => store.getters.browser);

		// 加载状态
		const loading = ref<boolean>(false);

		// 分页信息
		const pagination = reactive<any>({
			page: 1,
			size: 100,
			total: 0
		});

		// 关键字筛选
		const keyWord = ref<string>("");

		// 刷新列表
		async function refresh(params?: any) {
			loading.value = true;

			const res = await service.im.session
				.page({
					...pagination,
					keyWord: keyWord.value,
					params,
					order: "updateTime",
					sort: "desc"
				})
				.then((res: any) => {
					store.commit("SET_SESSION_LIST", res.list);
					Object.assign(pagination, res.pagination);
					return res;
				})
				.catch((err: string) => {
					ElMessage.error(err);
					return Promise.reject(err);
				});

			loading.value = false;
			return res;
		}

		// 搜索关键字
		function onSearch() {
			refresh({ page: 1 });
		}

		// 设置会话
		function setSession(item: any) {
			if (item) {
				store.commit("SET_SESSION", item);
				mitt.emit("message.refresh", { page: 1 });
			}
		}

		// 会话详情
		function toDetail(item?: any) {
			if (item) {
				// 点击关闭弹窗
				if (browser.value.isMini) store.commit("CLOSE_SESSION");

				// 设置为当前会话
				if (!session.value || session.value.id != item.id) {
					setSession(item);
				}
			} else {
				store.commit("CLEAR_SESSION");
			}
		}

		// 数据列表
		const list = computed(() => {
			return store.getters.sessionList
				.map((e: any) => {
					const { _text } = parseContent(e);
					return {
						...e,
						lastMessage: _text
					};
				})
				.sort((a: any, b: any) => {
					return a.updateTime < b.updateTime ? 1 : -1;
				});
		});

		// 右键菜单
		function openCM(e: any, id: any, index: number) {
			ContextMenu.open(e, {
				list: [
					{
						label: "删除",
						icon: "el-icon-delete",
						callback: (_: any, done: Function) => {
							service.im.session.delete({
								ids: id
							});

							list.value.splice(index, 1);

							if (id == session.value.id) {
								toDetail();
							}

							done();
						}
					}
				]
			});
		}

		// PC 端下首次请求读取第一个消息
		refresh().then((res: any) => {
			if (!isEmpty(res.list) && !browser.value.isMini) {
				setSession(res.list[0]);
			}
		});

		// 事件监听
		mitt.on("session.refresh", refresh);

		// 销毁
		onUnmounted(function () {
			mitt.off("session.refresh", refresh);
		});

		return {
			session,
			sessionVisible,
			browser,
			list,
			loading,
			pagination,
			keyWord,
			openCM,
			refresh,
			onSearch,
			toDetail
		};
	}
});
</script>

<style lang="scss" scoped>
.cl-chat-session {
	height: 100%;
	width: 0;
	transition: width 0.2s ease-in-out;
	border-radius: 5px;
	background-color: #fff;
	overflow: hidden;

	&.is-show {
		width: 250px;
		max-width: 100%;
		margin-right: 5px;
	}

	&.is-position {
		position: absolute;
		left: 5px;
		top: 51px;
		height: calc(100% - 56px);
		z-index: 3000;

		&.is-show {
			width: calc(100% - 10px);
		}
	}

	&__search {
		padding: 10px;
	}

	&__list {
		height: calc(100% - 52px);
		overflow: auto;

		li {
			display: flex;
			list-style: none;
			padding: 10px;
			border-left: 5px solid #fff;

			.avatar {
				margin-right: 12px;

				img {
					display: block;
					height: 40px;
					width: 40px;
					border-radius: 3px;
					background-color: #eee;
				}

				.el-badge {
					&__content {
						height: 14px;
						line-height: 14px;
						padding: 0 4px;
						background-color: #fa5151;
						border: 0;
					}
				}
			}

			.det {
				flex: 1;
				.name {
					font-size: 13px;
					margin-top: 1px;
				}

				.content {
					font-size: 12px;
					margin-top: 5px;
					color: #666;
				}

				.name,
				.content {
					overflow: hidden;
					text-overflow: ellipsis;
					display: -webkit-box;
					-webkit-box-orient: vertical;
					-webkit-line-clamp: 1;
				}
			}

			&.is-active {
				background-color: #eee;
				border-color: $color-primary;
			}

			&:hover {
				background-color: #eee;
				cursor: pointer;
			}
		}
	}

	&__empty {
		text-align: center;
		margin-top: 10px;
	}
}
</style>
