<template>
	<div class="voice-assistant">
		<el-segmented
			:options="[
				{
					value: '',
					label: '全部',
				},
				{
					value: 'user',
					label: '市民',
				},
				{
					value: 'agent',
					label: '坐席',
				},
			]"
			v-model="voiceType"
			@change="changeVoiceType"
			style="position: absolute; right: 0; top: -40px"
		/>
		<!-- 聊天框 -->
		<el-scrollbar class="h100" ref="scrollbarRef" max-height="400px" v-if="showMessageList.length" @click="stopScroll">
			<div class="chat-box" ref="chatBoxRef">
				<div v-for="(item, index) in showMessageList" :key="index" class="chat-item" :class="item?.body?.content?.callSentenceInfo?.role">
					<div v-if="item?.body?.content?.callSentenceInfo?.role === 'user'" class="user">
						<img v-lazy="getImageUrl('order/user.png')" alt="" class="user-avatar" src="" />
						<div class="user-name">
							{{ item.body?.content?.callerNumber }}
							<div class="user-date">{{ formatDate(item?.timestamps, 'YYYY-mm-dd HH:MM:SS') }}</div>
						</div>
						<div class="user-content">{{ item?.body?.content?.callSentenceInfo.text }}</div>
						<div class="user-tag">
							<el-tag v-for="tag in item?.tags" size="small">{{ tag.name }}</el-tag>
						</div>
					</div>
					<div v-else class="agent">
						<img v-lazy="getImageUrl('order/service.png')" alt="" class="agent-avatar" src="" />
						<div class="agent-name">
							<div class="agent-date">{{ formatDate(item?.timestamps, 'YYYY-mm-dd HH:MM:SS') }}</div>
							{{ item?.body?.content?.calledNumber }}
						</div>
						<div class="agent-content">{{ item?.body?.content?.callSentenceInfo.text }}</div>
						<div class="agent-tag">
							<el-tag v-for="tag in item?.tags" size="small">{{ tag.name }}</el-tag>
						</div>
					</div>
				</div>
				<el-text class="end-call" tag="p" v-if="talkEnd">-- 通话结束 --</el-text>
			</div>
		</el-scrollbar>
		<el-empty v-else :image-size="100" />
		<el-button @click.stop="keepScroll" class="keep-scroll" title="回到底部" circle v-if="!isScrollBottom && !talkEnd">
			<SvgIcon name="ele-ArrowDown" size="18px" />
		</el-button>
	</div>
</template>
<script setup lang="ts" name="orderAcceptVoiceAssistant">
import { nextTick, onActivated, onDeactivated, onMounted, reactive, ref, watch } from 'vue';
import { getImageUrl } from '@/utils/tools';
import { useRoute } from 'vue-router';
import { formatDate } from '@/utils/formatTime';
import mittBus from '@/utils/mitt';
import other from '@/utils/other';
import { submitLog } from '@/api/public/log';
import { getNowDateTime } from '@/utils/constants';
import { useTelStatus } from '@/stores/telStatus';
import { storeToRefs } from 'pinia';
import { Session } from '@/utils/storage';
// 消息列表
const messageList = ref<any>([
	/*	{
		body: {
			content: {
				callSentenceInfo: {
					text: '你好，我是小智，有什么可以帮您的吗？',
					role: 'agent',
				},
				calledNumber: '1009',
				callerNumber: '19136073037',
			},
		},
		timestamps: new Date().getTime(),
    tags: [
      {
        name: '语速过快',
      },
      {
        name: '语速过快',
      },
    ],
	},
	{
		body: {
			content: {
				callSentenceInfo: {
					text: '12311？',
					role: 'user',
				},
				calledNumber: '1009',
				callerNumber: '19136073037',
			},
		},
		timestamps: new Date().getTime(),
		tags: [
			{
				name: '语速过快',
			},
			{
				name: '语速过快',
			},
		],
	},*/
]); // 消息列表
const showMessageList = ref<EmptyArrayType>([
	/*{
		body: {
			content: {
				callSentenceInfo: {
					text: '你好，我是小智，有什么可以帮您的吗？',
					role: 'agent',
				},
				calledNumber: '1009',
				callerNumber: '19136073037',
			},
		},
		timestamps: new Date().getTime(),
    tags: [
      {
        name: '语速过快',
      },
      {
        name: '语速过快',
      },
    ],
	},
	{
		body: {
			content: {
				callSentenceInfo: {
					text: '12311？',
					role: 'user',
				},
				calledNumber: '1009',
				callerNumber: '19136073037',
			},
		},
		timestamps: new Date().getTime(),
    tags: [
      {
        name: '语速过快',
      },
      {
        name: '语速过快',
      },
    ],
	},*/
]);
const useTelStatusStore = useTelStatus();
const { telStatusInfo } = storeToRefs(useTelStatusStore); // 电话状态
const route = useRoute();
const fromTel = route.query?.fromTel ?? '';
const talkEnd = ref(false); // 通话结束
const wsReceive = (message: any) => {
	try {
		const data = JSON.parse(message.data);
		data.tags = data.tags || [];
		if (data.body.bisType === 3) {
			data.tags = data.tags || [];
			// 转写消息
			if (data.body.content.action === 0) {
				// 通话开始
				console.log('通话转写开始了');
				const name: string = `通话转写开始了,分机号：${telStatusInfo.value.telsNo},来电号码:${fromTel},callID:${data.body.content.callId}`;
				const remark: string = `通话转写开始了,分机号：${telStatusInfo.value.telsNo},,来电号码:${fromTel},callID:${data.body.content.callId}`;
				const request = {
					creationTime: new Date(),
					name,
					remark,
					executeUrl: import.meta.env.VITE_VOICE_ASSISTANT_SOCKET_URL,
				};
				submitLogFn(request);
				talkEnd.value = false;
			}
			if (data.body.content.action === 1) {
				// 通话中
				if (messageList.value.length) {
					const sameIndex = messageList.value.find(
						(item: any) => item.body.content.callSentenceInfo.index === data.body.content.callSentenceInfo.index
					);
					if (sameIndex) {
						sameIndex.body.content.callSentenceInfo.text = data.body.content.callSentenceInfo.text;
					} else {
						messageList.value = [...messageList.value, data];
					}
				} else {
					messageList.value = [...messageList.value, data];
				}
				scrollToBottom();
				filterMessage(voiceType.value, other.deepClone(messageList.value));
				console.log('通话消息转写内容：', showMessageList.value);
			}
			if (data.body.content.action === 4) {
				// 通话结束
				setTimeout(() => {
					//通话结束
					talkEnd.value = true;
					scrollToBottom(); //滚动到底部
					stopScroll(); //停止滚动
				}, 500);
				console.log('通话转写结束了');
				const name: string = `通话转写结束了,分机号：${telStatusInfo.value.telsNo},来电号码:${fromTel},callID:${data.body.content.callId}`;
				const remark: string = `通话转写结束了,分机号：${telStatusInfo.value.telsNo},,来电号码:${fromTel},callID:${data.body.content.callId}`;
				const request = {
					creationTime: new Date(),
					name,
					remark,
					executeUrl: import.meta.env.VITE_VOICE_ASSISTANT_SOCKET_URL,
				};
				submitLogFn(request);
			}
		}
	} catch (error) {
		console.log('坐席辅助收到消息', message);
	}
};
const voiceType = ref('');
// 选择坐席还是市民通话内容
const changeVoiceType = () => {
	filterMessage(voiceType.value, messageList.value);
};
// 记录日志
const submitLogFn = async (request: any) => {
	try {
		await submitLog(request);
	} catch (error) {
		console.log(error, getNowDateTime());
	}
};
const scrollbarRef = ref<RefType>();
const chatBoxRef = ref<RefType>();
// 停止滚动
const stopScroll = () => {
	isScrollBottom.value = false;
};
// 滚动到底部
const isScrollBottom = ref(true); // 是否需要滚动到底部
const isAutoScroll = ref(true); // 是否自动滚动
const scrollToBottom = async () => {
	if (!isScrollBottom.value) return;
	await nextTick(); // 等待 DOM 更新
	const max = chatBoxRef.value?.clientHeight;
	scrollbarRef.value?.setScrollTop(max);
	isAutoScroll.value = true;
};
watch(messageList.value, () => {
	scrollToBottom();
});
// 继续滚动
const keepScroll = () => {
	isScrollBottom.value = true;
	scrollToBottom();
};
watch(
	() => scrollbarRef.value?.wrapRef,
	() => {
		scrollbarRef.value?.wrapRef.addEventListener('mousewheel', () => {
			stopScroll();
		});
	}
);
// 订阅消息
const subscribe = () => {
	const currentRoute = tagsViewList.value.find((v: any) => v.query?.callId === state.ruleForm.callId);
	// 接受消息
	mittBus.on('wsReceive', (message: any) => {
		const data = JSON.parse(message.data);
		if (currentRoute && data.body.content.callId === currentRoute?.query?.callId) {
			// 判断是否是当前通话
			wsReceive(message);
		}
	});
	mittBus.on('wsNotice', (data: any) => {
		wsNotice(data);
	});
};
// 语音提醒内容
const tagList = ref<EmptyObjectType>([]);
const wsNotice = (message: any) => {
	try {
		const data = JSON.parse(message.data);
		if (data.body.bisType === 20) {
			//20代表语音提醒消息
			console.log(data.body.content[0].name, '语音提醒消息-坐席辅助');
			tagList.value.push(data.body.content[0]);
			for (let i of messageList.value) {
				if (i.body.content.callSentenceInfo.index === data.body.content[0].index) {
					i.tags.push(data.body.content[0]);
				}
			}
			filterMessage(voiceType.value, other.deepClone(messageList.value));
		}
	} catch (error) {
		console.log('坐席辅助收到消息', error);
	}
};
// 消息筛选
const filterMessage = (type: string,arr: any[]) => {
	switch (type) {
		case 'user':
			showMessageList.value = arr.filter((item: any) => item.body.content.callSentenceInfo.role === 'user');
			break;
		case 'agent':
			showMessageList.value = arr.filter((item: any) => item.body.content.callSentenceInfo.role === 'agent');
			break;
		case 'all':
			showMessageList.value = arr;
			break;
		default:
			showMessageList.value = arr;
			break;
	}
};
const tagsViewList = ref<EmptyArrayType>([]);
const state = reactive({
	ruleForm: {
		callId: '',
	},
});
onMounted(async () => {
	tagsViewList.value = await Session.get('tagsViewList');
	if (route.query.callId) {
		state.ruleForm.callId = route.query?.callId as string; // 通话id
	}
	// 进入页面订阅
	subscribe();
});
onActivated(() => {
	// 缓存进入重新订阅
	subscribe();
});
onDeactivated(() => {
	// 缓存离开取消订阅
	mittBus.off('wsReceive');
	mittBus.off('wsNotice');
});
defineExpose({
	filterMessage,
});
</script>

<style scoped lang="scss">
.voice-assistant {
	width: 100%;
	height: 100%;
	position: relative;
	.keep-scroll {
		position: absolute;
		right: 10px;
		bottom: 30px;
		z-index: 100;
	}
	.chat-box {
		width: 100%;
		padding-bottom: 50px;
		.agent {
			justify-content: flex-end;
		}

		.chat-item {
			word-break: break-all;
			position: relative;
			color: var(--el-color-white);
			margin: 10px 10px 20px 10px;
			display: flex;
			&:last-child {
				margin-bottom: 0;
			}
			.user {
				&-content {
					border-radius: var(--el-border-radius-base);
					background-color: var(--el-color-success);
					padding: 10px;
					position: relative;
					max-width: 400px;
					box-shadow: 4px 0 10px 0 rgba(0, 0, 0, 0.3);
					margin-left: 60px;

					&::after {
						position: absolute;
						content: '';
						top: calc(50% - 10px);
						left: -10px;
						width: 0;
						height: 0;
						border-top: 10px solid transparent;
						border-right: 10px solid var(--el-color-success);
						border-bottom: 10px solid transparent;
					}
				}

				&-name {
					font-size: var(--el-font-size-base);
					color: var(--el-text-color-regular);
					margin-bottom: 5px;
					margin-left: 65px;

					display: flex;
					justify-content: flex-end;
					align-items: center;
				}

				&-date {
					font-size: var(--el-font-size-extra-small);
					color: var(--el-text-color-placeholder);
					margin-left: 10px;
				}
				&-tag {
					margin-left: 65px;
					margin-top: 10px;
					:deep(.el-tag) {
						margin-right: 5px;
						margin-bottom: 5px;
					}
				}

				&-avatar {
					width: 40px;
					height: 40px;
					border-radius: 50%;
					position: absolute;
					left: 0;
					top: 16px;
				}
			}

			.agent {
				&-content {
					border-radius: var(--el-border-radius-base);
					background-color: var(--el-color-primary);
					padding: 10px;
					position: relative;
					justify-content: flex-end;
					max-width: 400px;
					box-shadow: -4px 0 10px 0 rgba(0, 0, 0, 0.3);
					margin-right: 60px;

					&::after {
						position: absolute;
						content: '';
						top: calc(50% - 10px);
						right: -10px;
						width: 0;
						height: 0;
						border-top: 10px solid transparent;
						border-left: 10px solid var(--el-color-primary);
						border-bottom: 10px solid transparent;
					}
				}

				&-name {
					font-size: var(--el-font-size-base);
					color: var(--el-text-color-regular);
					margin-bottom: 5px;
					text-align: right;
					margin-right: 65px;
					display: flex;
					justify-content: flex-end;
					align-items: center;
				}

				&-date {
					font-size: var(--el-font-size-extra-small);
					color: var(--el-text-color-placeholder);
					margin-right: 10px;
				}
				&-tag {
					margin-right: 65px;
					margin-top: 10px;
					text-align: right;
					:deep(.el-tag) {
						margin-right: 5px;
						margin-bottom: 5px;
					}
				}
				&-avatar {
					width: 40px;
					height: 40px;
					border-radius: 50%;
					position: absolute;
					right: 0;
					top: 16px;
				}
			}
		}
		.end-call {
			width: 100%;
			text-align: center;
			margin-top: 20px;
		}
	}
}
</style>
