<template>
	<el-config-provider :size="getGlobalComponentSize" :locale="zhCn" :message="messageConfig" :button="buttonConfig">
		<router-view v-show="setLockScreen" />
		<LockScreen v-if="themeConfig.isLockScreen" />
		<SetTings ref="setTingsRef" v-show="setLockScreen" />
		<CloseFull v-if="!themeConfig.isLockScreen" />
	</el-config-provider>
</template>

<script lang="tsx" name="app" setup>
import { computed, ref, onBeforeMount, onMounted, onBeforeUnmount, nextTick, watch, reactive, defineAsyncComponent } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import { storeToRefs } from 'pinia';
import { useTagsViewRoutes } from '@/stores/tagsViewRoutes';
import { useThemeConfig } from '@/stores/themeConfig';
import other from '@/utils/other';
import checkUpdate from '@/utils/checkUpdate';
import mittBus from '@/utils/mitt';
import { Session, Local, Cookie } from '@/utils/storage';
import setIntroduction from '@/utils/setIconfont';
import { loginPageInfo } from '@/api/login';
import { downloadFileByStream, getImageUrl } from '@/utils/tools';
import { useKeepALiveNames } from '@/stores/keepAliveNames';
import { useFavicon, useDark } from '@vueuse/core';
import { NextLoading } from '@/utils/loading';
import { ElMessageBox, ElNotification } from 'element-plus';
import { formatAxis, formatDate } from '@/utils/formatTime';
import { initFrontEndControlRoutes } from '@/router/frontEnd';
import { initBackEndControlRoutes } from '@/router/backEnd';
import { VxeUI, VxeButton } from 'vxe-pc-ui';
import MenuSvgIcon from '@/views/system/menu/components/Menu-svgIcon.vue';

// 式化日期，默认 yyyy-MM-dd HH:mm:ss
VxeUI.formats.add('formatDate', {
	tableCellFormatMethod({ cellValue }, format?: string) {
		return formatDate(cellValue, format || 'YYYY-mm-dd HH:MM:SS');
	},
});
// 创建一个简单的工具栏-右侧工具渲染
VxeUI.renderer.add('exportCurrent', {
	renderToolbarTool(renderOpts: any, params: any) {
		return (
			<VxeButton
				title="导出当前页"
				circle
				onClick={() => {
					const { $table } = params;
					const columns = $table.getColumns();
					const tableParams = $table.getParams();
					if (!tableParams) {
						VxeUI.modal.message({
							content: `参数错误请检查`,
							status: 'warning',
						});
						return;
					}

					const exportNewColumns = columns
						.map((item: any) => {
							return {
								prop: item.field,
								name: item.title,
								type: item.type,
							};
						})
						.filter((item: any) => item.prop && item.name && !['seq', 'checkbox'].includes(item.type));
					ElMessageBox.confirm(`您确定要导出当前页数据，是否继续?`, '提示', {
						confirmButtonText: '确认',
						cancelButtonText: '取消',
						type: 'warning',
						draggable: true,
						cancelButtonClass: 'default-button',
						autofocus: false,
					})
						.then(() => {
							VxeUI.modal.message({
								content: `导出中，请稍等`,
								status: 'loading',
								id: 'exportCurrent',
								duration: -1,
							});
							const request = {
								queryDto: tableParams.exportParams,
								columnInfos: exportNewColumns,
								isExportAll: false,
							};
							tableParams.exportMethod &&
								tableParams
									.exportMethod(request)
									.then((res: any) => {
										downloadFileByStream(res);
										VxeUI.modal.close('exportCurrent');
										VxeUI.modal.message({
											content: `导出成功`,
											status: 'success',
										});
									})
									.catch((e: any) => {
										console.log(`导出失败:${e}`);
										VxeUI.modal.close('exportCurrent');
										VxeUI.modal.message({
											content: `导出失败`,
											status: 'error',
										});
									});
						})
						.catch(() => {});
				}}
			>
				<MenuSvgIcon name="iconfont icon-daochu" />
			</VxeButton>
		);
	},
});
VxeUI.renderer.add('exportAll', {
	renderToolbarTool(renderOpts: any, params: any) {
		return (
			<VxeButton
				className="mr10"
				title="导出全部"
				circle
				onClick={() => {
					const { $table } = params;
					const columns = $table.getColumns();
					const tableParams = $table.getParams();
					if (!tableParams) {
						VxeUI.modal.message({
							content: `参数错误请检查`,
							status: 'warning',
						});
						return;
					}
					let request = {};
					if (tableParams.isSpecialExport) {
						// 特殊导出请求参数
						const exportNewColumns = columns.filter((item: any) => item.field && item.title && !['seq', 'checkbox'].includes(item.type));
						const addColumnName = exportNewColumns.map((item: any) => item.title);
						request = {
							...tableParams.exportParams,
							addColumnName,
						};
					} else {
						const exportNewColumns = columns
							.map((item: any) => {
								return {
									prop: item.field,
									name: item.title,
									type: item.type,
								};
							})
							.filter((item: any) => item.prop && item.name && !['seq', 'checkbox'].includes(item.type));
						request = {
							queryDto: tableParams.exportParams,
							columnInfos: exportNewColumns,
							isExportAll: true,
						};
					}

					ElMessageBox.confirm(`您确定要导出全部数据，是否继续?`, '提示', {
						confirmButtonText: '确认',
						cancelButtonText: '取消',
						type: 'warning',
						draggable: true,
						cancelButtonClass: 'default-button',
						autofocus: false,
					})
						.then(() => {
							VxeUI.modal.message({
								content: `导出中，请稍等`,
								status: 'loading',
								id: 'exportAll',
								duration: -1,
							});

							tableParams.exportMethod &&
								tableParams
									.exportMethod(request)
									.then((res: any) => {
										downloadFileByStream(res);
										VxeUI.modal.close('exportAll');
										VxeUI.modal.message({
											content: `导出成功`,
											status: 'success',
										});
									})
									.catch((e: any) => {
										console.log(`导出失败:${e}`);
										VxeUI.modal.close('exportAll');
										VxeUI.modal.message({
											content: `导出失败`,
											status: 'error',
										});
									});
						})
						.catch(() => {});
				}}
			>
				<MenuSvgIcon name="iconfont icon-export" />
			</VxeButton>
		);
	},
});

// 引入组件
const LockScreen = defineAsyncComponent(() => import('@/layout/lockScreen/index.vue'));
const SetTings = defineAsyncComponent(() => import('@/layout/navBars/breadcrumb/setings.vue'));
const CloseFull = defineAsyncComponent(() => import('@/layout/navBars/breadcrumb/closeFull.vue'));

const route = useRoute();
const stores = useTagsViewRoutes();
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
const storesKeepALiveNames = useKeepALiveNames();
const storesTagsViewRoutes = useTagsViewRoutes();
const { tagsViewRoutes } = storeToRefs(storesTagsViewRoutes);

// 设置锁屏时组件显示隐藏
const setLockScreen = computed(() => {
	// 防止锁屏后，刷新出现不相关界面
	// https://gitee.com/lyt-top/vue-next-admin/issues/I6AF8P
	return !themeConfig.value.isLockScreen;
});

// 可同时显示的消息最大数量
const messageConfig = reactive<any>({
	max: 3,
});
// 自动在两个中文字符之间插入空格
const buttonConfig = reactive<any>({
	autoInsertSpace: false,
});
// 获取全局组件大小
const getGlobalComponentSize = computed(() => {
	return other.globalComponentSize();
});
// 布局配置弹窗打开
const setTingsRef = ref<RefType>();
const openSetTingsDrawer = () => {
	setTingsRef.value.openDrawer();
};
// 设置初始化，防止刷新时恢复默认
onBeforeMount(async () => {
	try {
		// 获取登录页的背景图和系统名称等
		const { result } = await loginPageInfo();
		const globalTitle = result.sysName ?? ''; // 标题名称
		const loginImage = result.loginImage ? result.loginImage : `${getImageUrl('default/login_bg.png')}`; // 登录页背景图
		const isLoginMessageCode = result.isLoginMessageCode; // 是否开启短信验证码
		const appScope = result.appScope ?? 'YiBin'; // 应用范围
		const callCenterType = result.callCenterType ?? 'TianRun'; // 呼叫中心类型
		const cityName = result.cityName ?? ''; // 城市名称
		const cityCode = result.cityCode ?? ''; // 城市编码
		const cityAbbr = result.cityAbbr ?? ''; // 城市简称
		const locationCenter = result.locationCenter ?? []; // 城市中心点
		const operate = result.operate ?? ''; // 管理运营 页脚
		const techSupport = result.techSupport ?? ''; // 技术支持 页脚
		const recordNumber = result.recordNumber ?? ''; // 备案号 页脚
		const faviconImage = result.faviconImage ?? ``; // favicon 浏览器标签图标
		const menuLogoImage = result.menuLogoImage ?? ``; // 菜单logo
		const menuLogoImageMini = result.menuLogoImageMini ?? ``; // 菜单logo-mini
		const changPwdImage = result.changPwdImage ?? ``; // 修改密码图片
		const callCenterSocketUrl = result.callCenterSocketUrl ?? ''; // 呼叫中心socket地址
		const recordPrefix = result.recordPrefix ?? ''; // 录音前缀
		const recordDownLoadPrefix = result.recordDownLoadPrefix ?? ''; // 录音下载前缀
		storesThemeConfig.setThemeConfig(
			Object.assign(themeConfig.value, {
				globalTitle,
				loginImage,
				isLoginMessageCode,
				appScope,
				callCenterType,
				cityName,
				cityCode,
				cityAbbr,
				locationCenter,
				operate,
				techSupport,
				recordNumber,
				faviconImage,
				menuLogoImage,
				menuLogoImageMini,
				changPwdImage,
				callCenterSocketUrl,
				recordPrefix,
				recordDownLoadPrefix,
			})
		);
	} catch (e) {
		console.log(e);
	}
	// 设置批量第三方 icon 图标
	setIntroduction.cssCdn();
	// 设置批量第三方 js
	setIntroduction.jsCdn();
});
const router = useRouter();
// 登录成功后的跳转
const signInSuccess = (isNoPower: boolean | undefined) => {
	window.history.replaceState({}, document.title, window.location.pathname);
	if (isNoPower) {
		ElNotification({
			title: '提示',
			message: '抱歉，您没有登录权限，请联系管理员',
			type: 'warning',
		});
		Session.clear();
		Cookie.clear();
		Local.clear();
		setTimeout(() => {
			window.location.reload();
		}, 2000);
	} else {
		router.push('/');
		// 设置登录成功后的时间问候语
		const signInText = '欢迎回来！';
		ElNotification({
			type: 'success',
			title: `${formatAxis(new Date())}`,
			message: `${signInText}`,
			position: 'bottom-right',
		});
		NextLoading.start();
	}
};
// 页面加载时
onMounted(() => {
	nextTick(async () => {
		try {
			// 获取缓存中的布局配置
			if (Local.get('themeConfig')) {
				storesThemeConfig.setThemeConfig(Local.get('themeConfig'));
				document.documentElement.style.cssText = Local.get('themeConfigStyle');
			}

			// 开发环境不提示更新
			if (import.meta.env.VITE_MODE_NAME != 'development') {
				// 监听是否更新 半个小时检查一次
				await checkUpdate(1800);
			}
			// 监听布局配置弹窗点击打开
			mittBus.on('openSetTingsDrawer', () => {
				openSetTingsDrawer();
			});

			// 获取缓存中的全屏配置
			if (Session.get('isTagsViewCurrenFull')) {
				stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
			}
			// 清除某个页面的缓存
			mittBus.on('clearCache', (view: any) => {
				clearCacheTagsView(view);
			});
			// 解决火狐拖动打开新窗口
			document.body.ondrop = (event) => {
				event.preventDefault();
				event.stopPropagation();
			};
			// 动态修改icon
			const icon = useFavicon();
			icon.value = themeConfig.value.faviconImage; // 更改当前左上角角标
			const isDark = useDark();
			isDark.value = themeConfig.value.isIsDark; // 更改暗黑模式
			/*mittBus.on('*', (index, data) => {
        console.log(index, data);
      });*/

			// 通过url判断单点登录
			// 获取url特殊参数 实现登录跳转
			// 单点登录进来的参数
			const urlParams = new URLSearchParams(window.location.search);
			const source = urlParams.get('token');
			// 判断是否是单点登录
			if (source) {
				Cookie.remove('token');
				//登录
				// 存储 token 到浏览器缓存
				Cookie.set('token', source);
				if (!themeConfig.value.isRequestRoutes) {
					// 前端控制路由，2、请注意执行顺序
					const isNoPower = await initFrontEndControlRoutes();
					signInSuccess(isNoPower);
				} else {
					// 模拟后端控制路由，isRequestRoutes 为 true，则开启后端控制路由
					// 添加完动态路由，再进行 router 跳转，否则可能报错 No match found for location with path "/"
					const isNoPower = await initBackEndControlRoutes();
					// 执行完 initBackEndControlRoutes，再执行 signInSuccess
					signInSuccess(isNoPower);
				}
			}
		} catch (error) {
			console.log(error);
		}
	});
});
// 清除缓存 name
const clearCacheTagsView = async (routeName: string) => {
	let item: EmptyObjectType | null | undefined;
	tagsViewRoutes.value.forEach((v: any) => {
		if (v.name === routeName) {
			item = v;
		}
	});
	if (!item) return false;
	await storesKeepALiveNames.delCachedView(item);
	if (item.meta?.isKeepAlive) await storesKeepALiveNames.addCachedView(item);
};
// 页面销毁时，关闭监听布局配置/i18n监听
onBeforeUnmount(() => {
	mittBus.off('openSetTingsDrawer', () => {});
	mittBus.off('clearCache', () => {});
});
// 监听路由的变化，设置网站标题
watch(
	() => route.path,
	() => {
		other.useTitle();
	},
	{
		deep: true,
	}
);
</script>
