<template>
	<!--  :style="{ flex: layoutUserFlexNum }" -->
	<div class="layout-navBars-breadcrumb-user pr5">
		<!--		 <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange">
			<div class="layout-navBars-breadcrumb-user-icon mr10"  title="组件大小">
				<i class="iconfont icon-ziti"></i>
			</div>
			<template #dropdown>
				<el-dropdown-menu>
					<el-dropdown-item command="large" :disabled="state.disabledSize === 'large'">大型</el-dropdown-item>
					<el-dropdown-item command="default" :disabled="state.disabledSize === 'default'">默认</el-dropdown-item>
					<el-dropdown-item command="small" :disabled="state.disabledSize === 'small'">小型</el-dropdown-item>
				</el-dropdown-menu>
			</template>
		</el-dropdown>-->
		<div class="layout-navBars-breadcrumb-user-icon mr5" @click="onSearchClick" title="菜单搜索">
			<SvgIcon name="ele-Search" size="16px" />
		</div>
		<Search ref="searchRef" />
		<div class="layout-navBars-breadcrumb-user-icon mr5" @click="onLayoutSetTingClick" title="布局配置" v-if="showSetting">
			<SvgIcon name="icon-skin iconfont" size="18px" />
		</div>
		<div class="layout-navBars-breadcrumb-user-icon mr5" title="消息通知">
			<div class="layout-navBars-breadcrumb-user-icon">
				<el-popover
					placement="bottom"
					trigger="click"
					popper-class="user-news-box"
					transition="el-zoom-in-top"
					:width="300"
					:persistent="false"
					v-model:visible="newsVisible"
				>
					<template #reference>
						<el-badge :value="messageCount" :max="99" :hidden="messageCount <= 0">
							<SvgIcon name="ele-Bell" size="18px" />
						</el-badge>
					</template>
					<template #default>
						<user-news @hideNws="hideNws" />
					</template>
				</el-popover>
			</div>
		</div>
		<div class="layout-navBars-breadcrumb-user-icon mr5" @click="onLockScreen" title="锁屏">
			<SvgIcon name="ele-Lock" size="18px" />
		</div>
		<div class="layout-navBars-breadcrumb-user-link" :title="userInfos.name">
			<el-popover ref="popover" placement="bottom" :width="250" trigger="hover" popper-class="user-info-box" v-model:visible="userVisible">
				<template #reference>
					<div class="layout-navBars-breadcrumb-user-link-photoBox" @userVisible="userVisible = !userVisible">
						<el-avatar :src="userInfos.photo" :size="24" class="layout-navBars-breadcrumb-user-link-photo">
							<SvgIcon name="ele-UserFilled" color="var(--el-color-primary)" />
						</el-avatar>
						<span class="text-no-wrap layout-navBars-breadcrumb-user-link-photoBox-name">{{ userInfos.name ? userInfos.name : '' }}</span>
						<el-button link><SvgIcon name="ele-ArrowUp" class="mr5 arrow" :class="{ 'is-reverse': userVisible }" /></el-button>
					</div>
				</template>
				<div class="user-info-box-content">
					<div class="user-info-box-content-item">
						<span class="user-info-box-content-item-title">登录账号：</span
						><span class="user-info-box-content-item-content">{{ userInfos.account?.userName ?? '' }}</span>
					</div>
					<div class="mt5 user-info-box-content-item">
						<span class="user-info-box-content-item-title">工号：</span
						><span class="user-info-box-content-item-content">{{ userInfos.staffNo }}</span>
					</div>
					<div class="mt5 user-info-box-content-item">
						<span class="user-info-box-content-item-title">角色：</span
						><span class="user-info-box-content-item-content">{{ userInfos.roles.map((item) => item.displayName).join(',') }}</span>
					</div>
					<div class="mt5 user-info-box-content-item">
						<span class="user-info-box-content-item-title">组织：</span
						><span class="user-info-box-content-item-content">{{ userInfos.orgName }}</span>
					</div>
					<div class="mt5 flex-between">
						<el-button link type="primary" @click="onChangePwd"> <SvgIcon name="ele-Lock" class="mr3" />修改密码</el-button>
						<el-button link type="primary" @click="onLogOut"><SvgIcon name="iconfont icon-tuichu" class="mr3" />退出登录</el-button>
					</div>
				</div>
			</el-popover>
		</div>

		<!-- 锁频 -->
		<el-dialog v-model="dialogVisible" width="400px" draggable title="锁屏">
			<el-form :model="state.ruleForm" ref="ruleFormRef" @submit.native.prevent>
				<el-form-item label="锁屏密码" prop="pwd" :rules="[{ required: true, message: '请填写锁屏密码', trigger: 'blur' }]">
					<el-input show-password placeholder="请填写密码" v-model="state.ruleForm.pwd" @keyup.enter="confirmLock(ruleFormRef)">
						<template #prefix>
							<SvgIcon name="ele-Unlock" />
						</template>
					</el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="dialogVisible = false" class="default-button">取 消</el-button>
					<el-button type="primary" @click="confirmLock(ruleFormRef)">确 定</el-button>
				</span>
			</template>
		</el-dialog>

		<!-- 修改密码 -->
		<el-dialog v-model="showDutyDialog" draggable title="修改密码" width="500px">
			<el-form :model="state.dutyForm" label-width="80px" :rules="rules" ref="dutyFormRef">
				<el-form-item prop="currentPassword" label="旧密码" class="mb30">
					<el-input class="inputDeep" clearable show-password placeholder="请输旧就密码" v-model="state.dutyForm.currentPassword" autocomplete="off">
						<template #prefix>
							<SvgIcon name="ele-Unlock" />
						</template>
					</el-input>
				</el-form-item>
				<el-form-item label="新密码" prop="newPassword" class="mb30">
					<el-input class="inputDeep" clearable show-password placeholder="请填写新密码" v-model="state.dutyForm.newPassword" autocomplete="off">
						<template #prefix>
							<SvgIcon name="ele-Unlock" />
						</template>
					</el-input>
					<div class="intensity">
						<span class="psdText">密码强度：{{ modes === 1 ? '弱' : modes === 2 ? '中' : modes === 3 ? '强' : '' }}</span>
						<span class="line ruo" :class="modes === 1 ? 'low' : ''"></span>
						<span class="line zhong" :class="modes === 2 ? 'middle' : ''"></span>
						<span class="line qiang" :class="modes === 3 ? 'high' : ''"></span>
					</div>
				</el-form-item>
				<el-form-item prop="confirmPassword" label="确认密码">
					<el-input
						class="inputDeep"
						clearable
						type="password"
						show-password
						placeholder="请再次填写密码"
						v-model="state.dutyForm.confirmPassword"
						autocomplete="off"
					>
						<template #prefix>
							<SvgIcon name="ele-Unlock" />
						</template>
					</el-input>
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="showDutyDialog = false" class="default-button">取 消</el-button>
					<el-button type="primary" @click="save(dutyFormRef)" :loading="loading">保 存</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts" name="layoutBreadcrumbUser">
import { defineAsyncComponent, ref, computed, reactive, onMounted, onUnmounted } from 'vue';
import { ElMessageBox, ElMessage, ElNotification, FormInstance } from 'element-plus';
import { storeToRefs } from 'pinia';
import { useUserInfo } from '@/stores/userInfo';
import { useThemeConfig } from '@/stores/themeConfig';
import { Session, Local, Cookie } from '@/utils/storage';
import mittBus from '@/utils/mitt';
import { changePwd } from '@/api/login/user';
import { megcount } from '@/api/auxiliary/notice';
import signalR from '@/utils/signalR';
import { callCenterLogout, useGlobalState } from '@/utils/callCenter';

// 引入组件
const UserNews = defineAsyncComponent(() => import('@/layout/navBars/breadcrumb/userNews.vue'));
const Search = defineAsyncComponent(() => import('@/layout/navBars/breadcrumb/search.vue'));

const stores = useUserInfo();
const storesThemeConfig = useThemeConfig();
const { userInfos } = storeToRefs(stores);
const { themeConfig } = storeToRefs(storesThemeConfig);
const searchRef = ref<RefType>();
const state = reactive({
	isScreenFull: false,
	disabledI18n: 'zh-cn',
	disabledSize: 'large',
	dutyForm: {
		currentPassword: '',
		newPassword: '',
		confirmPassword: '',
	},
	ruleForm: {
		pwd: '', // 锁频密码
	},
});
//  检查密码强度
let modes = ref<number>(0);
const checkPassword = (rule: any, value: string, callback: any) => {
	if (!value) {
		modes.value = 0;
		return callback('新密码不能为空');
	}
	if (value.length < 8) {
		modes.value = 0;
		return callback('新密码不少于8位');
	}
	/*
	  最短8位， {6,}
	  可以包含小写大母 [a-z] 和大写字母 [A-Z]
	  可以包含数字 [0-9]
	  可以包含下划线 [ _ ] 和减号 [ - ]
	*/
	if (/^[\w_-]{6,}$/.test(state.dutyForm.newPassword)) {
		modes.value = 1;
	}
	/*
	  最短8位， {8,}
	  必须包含1个数字
	  必须包含1个小写字母
	  必须包含1个大写字母
	  必须包含1个特殊字符
	*/
	if (/^\S*(?=\S{8,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*.?])\S*$/.test(state.dutyForm.newPassword)) modes.value = 2; //中等
	/*
	  最短8位， {8,}
	  必须包含1个数字
	  必须包含1个小写字母
	  必须包含1个大写字母
	  必须包含2个特殊字符
	*/
	if (/^\S*(?=\S{8,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*.?]{2,})\S*$/.test(state.dutyForm.newPassword)) modes.value = 3; //强密码
	if (modes.value == 0 || modes.value == 1) {
		return callback('提示：密码不得少于8位数，且必须包含字母大小写和特殊字符'); //弱密码
	}
	if (value === state.dutyForm.currentPassword) {
		return callback('新密码不能与旧密码一致，请重新填写');
	}
	return callback();
};
// 检查填写密码是否一致
const checkConfirmPassword = (rule: any, value: any, callback: any) => {
	if (!value) {
		return callback('请再次填写密码');
	}
	if (value != state.dutyForm.newPassword) {
		return callback('两次密码填写不一致，请重新填写');
	}
	return callback();
};
const rules = reactive({
	currentPassword: [{ required: true, message: '请填写旧密码', trigger: ['change', 'blur'] }],
	newPassword: [{ required: true, validator: checkPassword, trigger: ['change', 'blur'] }],
	confirmPassword: [{ required: true, validator: checkConfirmPassword, trigger: 'blur' }],
});
const dialogVisible = ref(false);
// 设置分割样式
const layoutUserFlexNum = computed(() => {
	let num: string | number;
	const { layout, isClassicSplitMenu } = themeConfig.value;
	const layoutArr: string[] = ['defaults', 'columns'];
	if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1';
	else num = '';
	return num;
});
// 布局配置 icon 点击时
const onLayoutSetTingClick = () => {
	mittBus.emit('openSetTingsDrawer');
};
const userVisible = ref<boolean>(false); //是否显示用户信息
const newsVisible = ref<boolean>(false); //是否显示消息
const messageCount = ref<number>(0); //消息数量
// 获取数量
const getNumAndList = async () => {
	try {
		const [megcountRes] = await Promise.all([megcount()]);
		messageCount.value = megcountRes.result?.personCount + megcountRes.result?.orgCount;
	} catch (e) {
		console.log(e, '获取消息数量失败');
	}
};
// 隐藏消息
const hideNws = () => {
	newsVisible.value = false;
};

const dutyFormRef = ref<RefType>();
// 点击修改密码
const onChangePwd = () => {
	//  重置表单
	if (dutyFormRef.value) {
		dutyFormRef.value.resetFields();
	}
	showDutyDialog.value = true;
};
// 退出登录
const globalState = useGlobalState(); // 全局变量
const onLogOut = () => {
	if (globalState.callCenterIsOnThePhone) {
		// 正在通话中不允许退出登录
		ElMessage({
			message: '正在通话中,请先结束通话',
			type: 'warning',
			duration: 2000,
		});
		return;
	}
	if (globalState.callCenterIsSignIn) {
		ElMessageBox({
			closeOnClickModal: false,
			closeOnPressEscape: false,
			title: '提示',
			message: '检测到您未签出,本次退出系统将自动签出, 是否继续?',
			showCancelButton: true,
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			buttonSize: 'default',
			draggable: true,
			type: 'warning',
			autofocus: false,
			cancelButtonClass: 'default-button',
			showClose: false,
			beforeClose: (action, instance, done) => {
				if (action === 'confirm') {
					instance.confirmButtonLoading = true;
					instance.confirmButtonText = '退出中';
					setTimeout(() => {
						done();
						setTimeout(() => {
							instance.confirmButtonLoading = false;
						}, 300);
					}, 700);
				} else {
					done();
				}
			},
		})
			.then(() => {
				callCenterLogout()
					.then(() => {
						console.log('呼叫中心ws退出成功');
						signalR
							.leaveAllGroupAndStop()
							.then(() => {
								// 退出所有组
								console.log('业务中心ws退出成功');
								setTimeout(() => {
									// 清除缓存/token等
									Local.clear();
									Session.clear();
									Cookie.clear();
									// 使用 reload 时，不需要调用 resetRoute() 重置路由
									window.location.reload();
								}, 300);
							})
							.catch(() => {
								setTimeout(() => {
									// 清除缓存/token等
									Local.clear();
									Session.clear();
									Cookie.clear();
									// 使用 reload 时，不需要调用 resetRoute() 重置路由
									window.location.reload();
								}, 300);
							});
					})
					.catch(() => {
						setTimeout(() => {
							// 清除缓存/token等
							Local.clear();
							Session.clear();
							Cookie.clear();
							// 使用 reload 时，不需要调用 resetRoute() 重置路由
							window.location.reload();
						}, 300);
					});
			})
			.catch(() => {});
		return;
	}
	ElMessageBox({
		closeOnClickModal: false,
		closeOnPressEscape: false,
		title: '提示',
		message: '此操作将退出登录, 是否继续?',
		showCancelButton: true,
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		buttonSize: 'default',
		draggable: true,
		type: 'warning',
		autofocus: false,
		cancelButtonClass: 'default-button',
		showClose: false,
		beforeClose: (action, instance, done) => {
			if (action === 'confirm') {
				instance.confirmButtonLoading = true;
				instance.confirmButtonText = '退出中';
				setTimeout(() => {
					done();
					setTimeout(() => {
						instance.confirmButtonLoading = false;
					}, 300);
				}, 700);
			} else {
				done();
			}
		},
	})
		.then(async () => {
			signalR.leaveAllGroupAndStop().then(() => { // 退出所有组
				console.log('业务中心ws退出成功');
				setTimeout(() => {
					// 清除缓存/token等
					Local.clear();
					Session.clear();
					Cookie.clear();
					// 使用 reload 时，不需要调用 resetRoute() 重置路由
					window.location.reload();
				}, 300);
			}).catch(()=>{
				setTimeout(() => {
					// 清除缓存/token等
					Local.clear();
					Session.clear();
					Cookie.clear();
					// 使用 reload 时，不需要调用 resetRoute() 重置路由
					window.location.reload();
				}, 300);
			})
		})
		.catch(() => {});
};
// 菜单搜索点击
const onSearchClick = () => {
	searchRef.value.openSearch();
};
// 组件大小改变
const onComponentSizeChange = (size: string) => {
	Local.remove('themeConfig');
	themeConfig.value.globalComponentSize = size;
	Local.set('themeConfig', themeConfig.value);
	initComponentSize();
	window.location.reload();
};
// 初始化全局组件大小
const initComponentSize = () => {
	switch (Local.get('themeConfig').globalComponentSize) {
		case 'large':
			state.disabledSize = 'large';
			break;
		case 'default':
			state.disabledSize = 'default';
			break;
		case 'small':
			state.disabledSize = 'small';
			break;
	}
};
const ruleFormRef = ref<RefType>();
//  锁频
const onLockScreen = () => {
	ruleFormRef.value?.resetFields();
	ruleFormRef.value?.clearValidate();
	dialogVisible.value = true;
};
// 确定锁频
const confirmLock = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate((valid: boolean) => {
		if (!valid) return;
		themeConfig.value.isLockScreen = true;
		Local.set('themeConfig', themeConfig.value);
		Session.set('lockPwd', state.ruleForm.pwd);
		dialogVisible.value = false;
	});
};
const showDutyDialog = ref(false);
const loading = ref(false);
// 修改密码保存
const save = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate((valid: boolean) => {
		if (!valid) return;
		loading.value = true;
		changePwd(state.dutyForm)
			.then(async () => {
				ElNotification({
					title: '成功',
					type: 'success',
					message: '密码修改成功，请重新登录',
				});
				setTimeout(() => {
					loading.value = false;
					// 使用 reload 时，不需要调用 resetRoute() 重置路由
					window.location.reload();
					// 清楚缓存
					Session.clear();
					Cookie.clear();
					Local.clear();
				}, 1000);
			})
			.catch(() => {
				showDutyDialog.value = false;
				loading.value = false;
			});
	});
};
// 开发环境不显示设置
const showSetting = computed(() => {
	return import.meta.env.VITE_MODE_NAME === 'development';
});
// 页面加载时
onMounted(() => {
	if (Local.get('themeConfig')) {
		initComponentSize();
	}
	signalR.SR?.on('CircularRecord', (data) => {
		// 小红点数量消息通知
		console.log(data, '小红点数量消息通知');
		getNumAndList();
	});
	getNumAndList();
});
onUnmounted(() => {
	signalR.SR.off('CircularRecord');
});
</script>

<style scoped lang="scss">
.layout-navBars-breadcrumb-user {
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: flex-end;

	&-link {
		white-space: nowrap;
		text-align: center;
		flex: 1;
		&-photo {
			background-color: var(--hotline-bg-main-color);
			border: 2px solid var(--el-color-primary);
			margin-right: 5px;
		}
		&-photoBox {
			display: flex;
			justify-content: center;
			align-items: center;
			cursor: pointer;
			&-name {
				max-width: 150px;
				overflow: hidden;
			}
		}
	}

	&-icon {
		padding: 0 6px;
		cursor: pointer;
		color: var(--hotline-color-text-main);
	}
	.arrow {
		transition: transform var(--el-transition-duration);
		cursor: pointer;
	}
	.arrow.is-reverse {
		transform: rotateZ(-180deg);
	}
	:deep(.el-dropdown) {
		color: var(--hotline-color-text-main);
		flex: 1;
	}
	.intensity {
		.psdText {
			font-size: 14px;
			margin-right: 10px;
			color: #5a5a5a;
		}

		.line {
			display: inline-block;
			width: 48px;
			height: 10px;
			background: #d8d8d8;
			margin-right: 2px;

			&.ruo {
				border-radius: 6px 0 0 6px;
			}

			&.low {
				background: #bfcdff;
			}

			&.middle {
				background: #93a6fa;
			}

			&.high {
				background: #3c50e0;
			}

			&.qiang {
				border-radius: 0 6px 6px 0;
			}
		}

		.level {
			margin: 0 16px 0 8px;
		}
	}
}
</style>
<style lang="scss">
.user-news-box {
	height: 400px;
}
.user-info-box {
	&-content {
		&-item {
			display: flex;
			align-content: center;
			&-title {
				display: inline-block;
				width: 70px;
				text-align: right;
			}
			&-content {
				flex: 1;
			}
		}
	}
}
</style>
