<template>
	<!-- 经典布局 -->
	<template v-if="layout === 'classical'">
		<a-layout>
			<a-layout-sider
				v-model:collapsed="menuIsCollapse"
				:theme="menuTheme"
				:trigger="null"
				collapsible
				width="210"
				:style="{backgroundColor: themeColor}"
			>
				<header id="headerLogo" class="header-logo"
						style="background-color: #5C7CEC;border-bottom: none;padding-top: 20px">
					<div class="header-left">
						<div class="logo-bar">
							<img class="logo" src="/img/login_logo.png"/>
							<span style="color: white;margin-left: 20px" v-if="!menuIsCollapse">{{ sysBaseConfig.SYS_NAME }}</span>
						</div>
					</div>
				</header>
				<div :class="menuIsCollapse ? 'aminui-side isCollapse' : 'aminui-side'" style="margin-top: 20px;">
					<div class="adminui-side-scroll">
						<a-menu
							:style="{backgroundColor: themeColor}"
							v-model:openKeys="openKeys"
							v-model:selectedKeys="selectedKeys"
							mode="inline"
							theme="dark"
							@select="onSelect"
							@openChange="onOpenChange"
						>
							<NavMenu :nav-menus="menu"/>
						</a-menu>
					</div>
				</div>
			</a-layout-sider>
			<!-- 右侧布局 -->
			<a-layout>
				<a-layout-header id="header" class="header"
								 :style="{backgroundColor:topHanderThemeColorOpen?primaryColor:colorBgElevated,padding:0}">
					<div class="header-left" style="padding-left: 0px">
						<MenuUnfoldOutlined v-if="menuIsCollapse" @click="menuIsCollapseClick" style="padding:0 24px"/>
						<MenuFoldOutlined v-else @click="menuIsCollapseClick" style="padding:0 24px"/>
						<moduleMenu @switchModule="switchModule"/>
						<Topbar v-if=" breadcrumbOpen"/>
					</div>
					<div class="header-right">
						<userbar/>
					</div>
				</a-layout-header>
				<!-- 多标签 -->
				<Tags v-if="layoutTagsOpen"/>
				<a-layout-content class="main-content-wrapper">
					<div id="adminui-main" class="adminui-main">
						<router-view v-slot="{ Component }">
							<keep-alive :include="keepLiveRoute">
								<component :is="Component" :key="$route.name" v-if="routeShow"/>
							</keep-alive>
						</router-view>
						<iframe-view/>
						<div class="main-bottom-wrapper">
						</div>
					</div>
				</a-layout-content>
			</a-layout>
		</a-layout>
	</template>

	<!-- 双排菜单布局 -->
	<template v-else-if="layout === 'doublerow'">
		<a-layout>
			<a-layout-sider width="80" :trigger="null" collapsible :theme="menuTheme">
				<header id="headerLogo" class="header-logo"
						:style="{backgroundColor:topHanderThemeColorSpread?primaryColor:colorBgElevated}">
					<div class="header-left">
						<div class="logo-bar">
							<router-link to="/">
								<img class="logo" :title="sysBaseConfig.SYS_NAME"
									 :src="sysBaseConfig.SYS_LOGO"/>
							</router-link>
						</div>
					</div>
				</header>
				<a-menu v-model:selectedKeys="doublerowSelectedKey"
						:theme="menuTheme"
						class="doublerow-layout-menu">
					<a-menu-item
						v-for="item in menu"
						:key="item.path"
						style="
							text-align: center;
							border-radius: 2px;
							height: auto;
							line-height: 20px;
							flex: none;
							display: block;
							padding: 12px 0 !important;
						"
						@click="showMenu(item)"
					>
						<a
							v-if="item.meta && item.meta.type === 'link'"
							:href="item.path"
							target="_blank"
							@click.stop="() => {}"
						></a>
						<template #icon>
							<component :is="item.meta.icon" style="padding-left: 10px"/>
						</template>
						<div class="doublerow-layout-menu-item-fort-div">
							<span class="doublerow-layout-menu-item-fort-div-span">
								{{ item.meta.title }}
							</span>
						</div>
					</a-menu-item>
				</a-menu>
			</a-layout-sider>
			<a-layout-sider
				v-show="layoutSiderDowbleMenu"
				v-model:collapsed="menuIsCollapse"
				:trigger="null"
				width="170"
				collapsible
				:theme="menuTheme"
			>
				<div v-if="!menuIsCollapse" id="doublerowSideTop" class="doublerow-side-top">
					<h2 class="title">{{ pmenu.meta.title }}</h2>
				</div>
				<a-menu
					v-model:collapsed="menuIsCollapse"
					v-model:openKeys="openKeys"
					v-model:selectedKeys="selectedKeys"
					mode="inline"
					:theme="menuTheme"
					@select="onSelect"
				>
					<NavMenu :nav-menus="nextMenu"/>
				</a-menu>
			</a-layout-sider>
			<a-layout>
				<a-layout-header id="header" class="header"
								 :style="{backgroundColor:topHanderThemeColorOpen?primaryColor:colorBgElevated,padding:0}">
					<div class="header-left" style="padding-left: 0px">
						<MenuUnfoldOutlined v-if="menuIsCollapse" @click="menuIsCollapseClick" style="padding:0 24px"/>
						<MenuFoldOutlined v-else @click="menuIsCollapseClick" style="padding:0 24px"/>
						<moduleMenu @switchModule="switchModule"/>
						<Topbar v-if=" breadcrumbOpen"/>
					</div>
					<div class="header-right">
						<userbar/>
					</div>
				</a-layout-header>
				<!-- 多标签 -->
				<Tags v-if="!layoutTagsOpen"></Tags>
				<a-layout-content class="main-content-wrapper">
					<div id="adminui-main" class="adminui-main">
						<router-view v-slot="{ Component }">
							<keep-alive :include="keepLiveRoute">
								<component :is="Component" v-if="routeShow" :key="$route.name"/>
							</keep-alive>
						</router-view>
						<iframe-view/>
						<div class="main-bottom-wrapper">
							<!--							<a style="color: #a0a0a0" :href="sysBaseConfig.SYS_COPYRIGHT_URL" target="_blank">{{-->
							<!--									sysBaseConfig.SYS_COPYRIGHT-->
							<!--								}}</a>-->
						</div>
					</div>
				</a-layout-content>
			</a-layout>
		</a-layout>
	</template>

	<!-- 退出最大化 -->
	<div class="main-maximize-exit" @click="exitMaximize">
		<fullscreen-exit-outlined style="color: #fff"/>
	</div>
</template>

<script>
import Topbar from "./components/topbar.vue";
import Tags from "./components/tags.vue";
import NavMenu from "./components/NavMenu.vue";
import userbar from "./components/userbar.vue";
import iframeView from "./components/iframeView.vue";
import moduleMenu from "./components/moduleMenu.vue";
import {ThemeModeEnum} from "@/utils/enum";
import {globalStore, keepAliveStore} from "@/store";
import {mapState, mapStores, mapActions} from "pinia";
import tool from "@/utils/tool";
import dayjs from "dayjs";
import router from "@/router";
import {createVNode} from "vue";
import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
import {message, theme as antTheme} from "ant-design-vue";
import loginApi from "@/api/auth/loginApi";

export default defineComponent({
	name: "Index",
	components: {
		Topbar,
		Tags,
		NavMenu,
		userbar,
		moduleMenu,
		iframeView
	},
	data() {
		return {
			userInfo: tool.data.get("USER_INFO"),
			menu: [],
			moduleMenu: [],
			nextMenu: [],
			pmenu: {},
			doublerowSelectedKey: [],
			layoutSiderDowbleMenu: true,
			onSelectTag: false,
			selectedKeys: [],
			openKeys: [],
			openKeysOther: [],
			currentTime: dayjs().format("YYYY年MM月DD日 HH时mm分ss秒")
		};
	},
	computed: {
		...mapStores(globalStore),
		...mapState(globalStore, [
			"theme",
			"themeColor",
			"layout",
			"layoutTagsOpen",
			"menuIsCollapse",
			"breadcrumbOpen",
			"topHanderThemeColorOpen",
			"topHanderThemeColorSpread",
			"topHanderThemeColor",
			"sideUniqueOpen",
			"sysBaseConfig"
		]),
		...mapState(keepAliveStore, ["keepLiveRoute", "routeShow"]),
		primaryColor() {
			const p = antTheme.useToken().token.value.colorPrimary;
			return p
		},
		primaryColor1() {
			return antTheme.useToken().token.value.colorPrimaryBg;
		},
		primaryColor10() {
			return antTheme.useToken().token.value.colorPrimaryActive;
		},
		colorBgElevated() {
			return antTheme.useToken().token.value.colorBgContainer;
		},
		sideTheme() {
			const theme = this.theme;
			return theme === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : theme;
		},
		realTheme() {
			const theme = this.theme;
			return theme;
		},
		menuTheme() {
			const theme = this.theme;
			return theme === ThemeModeEnum.LIGHT ? 'light' : 'dark';
		},
		secondMenuSideTheme() {
			const theme = this.theme;
			return theme === ThemeModeEnum.REAL_DARK ? ThemeModeEnum.DARK : ThemeModeEnum.LIGHT;
		}
	},
	watch: {
		$route() {
			this.showThis();
		},
		layout: {
			handler(val) {
				document.body.setAttribute("data-layout", val);
				if (val.includes("doublerow")) {
					this.setDoublerowSelectedKey();
				}
				this.$nextTick(() => {
					// 顶栏主题色
					this.switchoverTopHanderThemeColor();
				});
			},
			immediate: true
		},
		topHanderThemeColorOpen() {
			this.switchoverTopHanderThemeColor();
		},
		topHanderThemeColorSpread() {
			this.switchoverTopHanderThemeColor();
		}
	},
	created() {
		// 判断浏览器宽度，顺手加入缓存
		this.onLayoutResize();
		window.addEventListener("resize", this.onLayoutResize);
		this.moduleMenu = this.$router.getMenu();
		// 获取缓存中的菜单模块是哪个
		const menuModuleId = tool.data.get("MENU_MODULE_ID");
		let menu = [];
		if (menuModuleId) {
			// 防止切换一个无此应用的人
			const module = this.$router.getMenu().filter((item) => item.id === menuModuleId);
			if (module.length > 0) {
				menu = module[0].children;
			} else {
				menu = this.$router.getMenu()[0].children;
			}
		} else {
			menu = this.$router.getMenu()[0].children;
		}
		// 此菜单为正常模块下的菜单
		this.menu = this.filterUrl(menu);
		this.showThis();

		window.setInterval(() => {
			this.currentTime = dayjs().format("YYYY年MM月DD日 HH时mm分ss秒");
		}, 1000);
	},
	mounted() {
		this.switchoverTopHanderThemeColor();
	},
	methods: {
		...mapActions(globalStore, ["setTheme", "setLayout", "setMenuIsCollapse"]),
		// 个人信息
		handleUser(key) {
			if (key === "uc") {
				router.push({path: "/usercenter"});
			}
			if (key === "clearCache") {
				this.$confirm({
					title: "提示",
					content: "确认清理所有缓存？",
					icon: createVNode(ExclamationCircleOutlined),
					maskClosable: false,
					okText: "确定",
					cancelText: "取消",
					onOk() {
						message.loading("正在清理中...", 1);
						tool.data.clear();
						setTimeout(() => {
							router.replace({path: "/login"});
							location.reload();
						}, 100);
					},
					onCancel() {
					}
				});
			}
			if (key === "outLogin") {
				this.$confirm({
					title: "提示",
					content: "确认退出当前用户？",
					icon: createVNode(ExclamationCircleOutlined),
					maskClosable: false,
					onOk() {
						// 取得缓存中的token
						const token = tool.data.get("TOKEN");
						const param = {
							token: token
						};
						message.loading("退出中...", 1);
						loginApi
							.logout(param)
							.then(() => {
								// message.c
								// 清理掉个人的一些信息
								tool.data.remove("TOKEN");
								tool.data.remove("USER_INFO");
								tool.data.remove("MENU");
								tool.data.remove("PERMISSIONS");
								router.replace({path: "/login"});
							})
							.catch(() => {
								tool.data.clear();
								router.replace({path: "/login"});
								location.reload();
							});
					},
					onCancel() {
					}
				});
			}
		},
		// 切换应用
		switchModule(id) {
			const menu = this.moduleMenu;
			if (menu.length > 0) {
				const menus = menu.filter((item) => item.id === id)[0].children;
				if (menus.length > 0) {
					// 将此模块的唯一值加入缓存
					tool.data.set("MENU_MODULE_ID", id);
					// 正儿八百的菜单
					this.menu = this.filterUrl(menus);
					// 然后将其跳转至指定界面，默认始终取排序第一的
					const path = this.traverseChild(this.menu);
					this.$router.push({path});
				} else {
					this.$message.warning("该模块下无任何菜单");
				}
			}
		},
		// 遍历子集获取一个path
		traverseChild(menu) {
			if (menu[0].children !== undefined) {
				if (menu[0].children.length > 0) {
					return this.traverseChild(menu[0].children);
				} else {
					return menu[0].path;
				}
			} else {
				return menu[0].path;
			}
		},
		// 当菜单被选中时
		onSelect(obj) {
			this.onSelectTag = true;
			const pathLength = obj.keyPath.length;
			const path = obj.keyPath[pathLength - 1];
			this.$router.push({path});
			// 设置选中
			this.selectedKeys = obj.selectedKeys;
		},
		onLayoutResize() {

		},
		// 路由监听高亮
		showThis() {
			this.pmenu = this.$route.meta.breadcrumb ? this.$route.meta.breadcrumb[0] : {};
			const nextTickMenu = this.filterUrl(this.pmenu.children);
			this.$nextTick(() => {
				let routeMenu = this.filterUrl(this.pmenu.children);
				const active = this.$route.meta.active || this.$route.fullPath;
				const parentPathArray = this.getParentKeys(routeMenu, active);
				if (parentPathArray) {
					const parentPath = parentPathArray[parentPathArray.length - 1];
					// 这一串操作下来只为取到最上面的路由的孩子们，最后成为双排菜单的第二排
					const nextMenuTemp = nextTickMenu.filter((item) => item.path === parentPath)[0].children;
					if (nextMenuTemp) {
						this.nextMenu = nextTickMenu.filter((item) => item.path === parentPath)[0].children;
					}
				}
				this.selectedKeys = new Array(active);
				if (!this.onSelectTag) {
					const pidKey = this.getParentKeys(this.menu, active);
					this.openKeys = pidKey;
				} else if (this.sideUniqueOpen) {
					const pidKey = this.getParentKeys(this.menu, active);
					this.openKeys = pidKey;
				}
				// 双排菜单下
				if (this.layout === "doublerow") {
					this.setDoublerowSelectedKey();
				}
			});
		},
		// 双排菜单下点击显示右侧分栏
		showMenu(route) {
			this.pmenu = route;
			if (this.pmenu.children) {
				this.nextMenu = this.filterUrl(this.pmenu.children);
			}
			if (!route.children || route.children.length === 0) {
				this.layoutSiderDowbleMenu = false;
				this.$router.push({path: route.path});
			} else {
				this.layoutSiderDowbleMenu = true;
			}
			if (this.layout === "doublerow") {
				this.doublerowSelectedKey = [route.path];
			}
		},
		// 设置双排菜单下的首列默认选中
		setDoublerowSelectedKey() {
			const pidKey = this.getParentKeys(this.menu, this.selectedKeys.toString());
			this.$nextTick(() => {
				const pidKeyArray = [];
				for (const key in pidKey) {
					pidKeyArray.push(key);
				}
				if (pidKeyArray.length > 1) {
					this.layoutSiderDowbleMenu = true;
				} else {
					this.layoutSiderDowbleMenu = false;
				}
			});
			// 设置第一排选中的
			this.menu.forEach((item) => {
				if (pidKey !== undefined) {
					if (pidKey[pidKey.length - 1].toString() === item.path) {
						this.doublerowSelectedKey = [item.path];
					}
				}
			});
		},
		// 菜单展开/关闭的回调
		onOpenChange(keys) {
			if (this.sideUniqueOpen) {
				// 获取最新的
				const openKey = keys[keys.length - 1];
				if (keys.length > 1) {
					// 获取上级
					const pidKey = this.getParentKeys(this.menu, openKey);
					this.openKeys = pidKey;
				} else {
					this.openKeys = Array.of(openKey); // new Array(openKey);
				}
			} else {
				this.openKeys = keys;
			}
		},
		// 获取上级keys
		getParentKeys(data, val) {
			// 递归父级key
			for (const element of data) {
				if (element.path === val) {
					return [element.path];
				}
				if (element.children) {
					const far = this.getParentKeys(element.children, val);
					if (far) {
						return far.concat(element.path);
					}
				}
			}
		},
		// 转换外部链接的路由
		filterUrl(map) {
			const newMap = [];
			// eslint-disable-next-line no-unused-expressions
			map &&
			map.forEach((item) => {
				item.meta = item.meta ? item.meta : {};
				// 处理隐藏
				if (item.meta.hidden) {
					return false;
				}
				// 处理http
				if (item.meta.type === "iframe") {
					item.path = `/i/${item.name}`;
				}
				// 递归循环
				if (item.children && item.children.length > 0) {
					item.children = this.filterUrl(item.children);
				}
				newMap.push(item);
			});
			return newMap;
		},
		menuIsCollapseClick() {
			this.globalStore.toggleConfig("menuIsCollapse");
		},
		// 退出最大化
		exitMaximize() {
			document.getElementById("app").classList.remove("main-maximize");
		},
		// 切换顶栏颜色
		switchoverTopHanderThemeColor() {
			// 界面顶栏设置颜色
			const header = document.getElementById("header");
			this.topHanderThemeColorOpen
				? header.classList.add("header-primary-color")
				: header.classList.remove("header-primary-color");
			// 判断是否开启了通栏
			const headerLogin = document.getElementById("headerLogo");
			try {
				this.topHanderThemeColorSpread
					? headerLogin.classList.add("header-logo-primary-color")
					: headerLogin.classList.remove("header-logo-primary-color");
			} catch (e) {
			}
			// 如果是双排菜单，吧第二排的也给渲染了
			if (this.layout === "doublerow") {
				const doublerowSideTop = document.getElementById("doublerowSideTop");
				try {
					this.topHanderThemeColorSpread
						? doublerowSideTop.classList.add("doublerow-side-top-primary-color")
						: doublerowSideTop.classList.remove("doublerow-side-top-primary-color");
				} catch (e) {
				}
			}
		}
	}
});
</script>

<style scoped>
:deep(.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected) {
	background: #EBF1FF;
	border-radius: 0px 20px 20px 0px;
	color: #5B7CEC;
}
:deep(.ant-menu){
	font-family: PingFang SC;
}
:deep(.ant-menu:not(.ant-menu-horizontal) .ant-menu-item) {
	/*
	margin-left: 0;
	*/
}

:deep(.ant-menu-dark.ant-menu-inline .ant-menu-sub.ant-menu-inline) {
	background: #5C7CEC;
}
</style>
