import { store } from '/@/store/index.ts';
import { Session } from '/@/utils/storage';
import { NextLoading } from '/@/utils/loading';
import { setFilterMenuAndCacheTagsViewRoutes, formatTwoStageRoutes, formatFlatteningRoutes } from '/@/router/index';
import router from '/@/router/index';
import { dynamicRoutes, notFoundAndNoPower  } from '/@/router/route';
import { listResources } from '/@/api/menu/index';
import { i18n } from '/@/i18n/index';

const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
/**
 * 获取目录下的 .vue、.tsx 全部文件
 * @method import.meta.glob
 * @link 参考：https://cn.vitejs.dev/guide/features.html#json
 */
const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...layouModules }, { ...viewsModules });

/**
 * 后端控制路由：初始化方法，防止刷新时路由丢失
 * @method  NextLoading 界面 loading 动画开始执行
 * @method store.dispatch('userInfos/setUserInfos') 触发初始化用户信息
 * @method store.dispatch('requestOldRoutes/setBackEndControlRoutes') 存储接口原始路由（未处理component），根据需求选择使用
 * @method setAddRoute 添加动态路由
 * @method setFilterMenuAndCacheTagsViewRoutes 设置递归过滤有权限的路由到 vuex routesList 中（已处理成多级嵌套路由）及缓存多级嵌套数组处理后的一维数组
 */
export async function initBackEndControlRoutes() {
	console.log('路由前值起')
	// 界面 loading 动画开始执行
	if (window.nextLoading === undefined) NextLoading.start();
	// 无 token 停止执行下一步
	if (!Session.get('token')) return false;
	// 触发初始化用户信息
	 await store.dispatch('userInfos/setUserInfos');
	// 获取路由菜单数据
	console.log('--------------')
	const res = await getBackEndControlRoutes();
	// 存储接口原始路由（未处理component），根据需求选择使用
	store.dispatch('requestOldRoutes/setBackEndControlRoutes', JSON.parse(JSON.stringify(res.data)));
	// 处理路由（component），替换 dynamicRoutes（/@/router/route）第一个顶级 children 的路由
	dynamicRoutes[0].children = await backEndComponent(res.data);
	// 添加动态路由
	await setAddRoute();
	// 设置递归过滤有权限的路由到 vuex routesList 中（已处理成多级嵌套路由）及缓存多级嵌套数组处理后的一维数组
	setFilterMenuAndCacheTagsViewRoutes();
}

/**
 * 添加动态路由
 * @method router.addRoute
 * @description 此处循环为 dynamicRoutes（/@/router/route）第一个顶级 children 的路由一维数组，非多级嵌套
 * @link 参考：https://next.router.vuejs.org/zh/api/#addroute
 */
export async function setAddRoute() {
	await setFilterRouteEnd().forEach((route: any) => {
		router.addRoute(route);
	});
}


/**
 * 处理路由格式及添加捕获所有路由或 404 Not found 路由
 * @description 替换 dynamicRoutes（/@/router/route）第一个顶级 children 的路由
 * @returns 返回替换后的路由数组
 */
export function setFilterRouteEnd() {
	let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));
	// notFoundAndNoPower 防止 404、401 不在 layout 布局中，不设置的话，404、401 界面将全屏显示
	// 关联问题 No match found for location with path 'xxx'
	filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];
	return filterRouteEnd;
}

/**
 * 请求后端路由菜单接口
 * @description isRequestRoutes 为 true，则开启后端控制路由
 * @returns 返回后端路由菜单数据
 */
export function getBackEndControlRoutes() {backEndComponent
	// 模拟 admin 与 test
	console.log(store.state.userInfos,'看看我的xuex用户信息')
	const auth = store.state.userInfos.userInfos.roles?.length ?( store.state.userInfos.userInfos.roles[0]) : [];
	// 管理员 admin
	if (auth === 'admin') return listResources();
	// 其它用户 test
	else return listResources();
}

/**
 * 重新请求后端路由菜单接口
 * @description 用于菜单管理界面刷新菜单（未进行测试）
 * @description 路径：/src/views/system/menu/component/addMenu.vue
 */
export function  setBackEndControlRefreshRoutes() {
	initBackEndControlRoutes()
	
}

/**
 * 后端路由 component 转换
 * @param routes 后端返回的路由表数组
 * @returns 返回处理成函数后的 component
 */
export function backEndComponent(routes: any) {
	if (!routes) return;
	const list=[];
	if (store.state.userInfos.userInfos.roles?.length) {
	if(store.state.userInfos.userInfos.roles.findIndex(ro=>ro==='admin')>=0){
		routes.forEach(el => {
			const mo={
				id:el.mainResource.id,
				resourceLevel:1,
				code:el.mainResource.code,
				path: el.mainResource.resourcePath,
				resourceSortOrder:el.mainResource.resourceSortOrder,
				name: el.mainResource.resourceName,
				title:i18n.global.t(el.mainResource.resourceMetaTitle),
				resourceComponent:el.mainResource.resourceComponent,
				redirect:el.mainResource.resourceRedirect,
				component:dynamicImport(dynamicViewsModules, el.mainResource.resourceComponent as string),
				meta: {
					// cache: false,
					title: el.mainResource.resourceMetaTitle,
					isLink: '',
					isHide: el.mainResource.resourceMetaIshide===0? false:true,
					isKeepAlive: el.mainResource.resourceMetaIskeepalive===0? false:true,
					isAffix: el.mainResource.resourceMetaIsaffix===0? false:true,
					isIframe: el.mainResource.resourceMetaIslframe===0? false:true,
					icon: el.mainResource.resourceMetaIcon,
				},
				children:[]
			}
			if(el.subResources.length>0){
				el.subResources.forEach(e => {
					let mu={
						id:e.subResource.id,
						resourceLevel:2,
						code:e.subResource.code,
						path: e.subResource.resourcePath,
						resourceSortOrder:e.subResource.resourceSortOrder,
						name: e.subResource.resourceName,
						title:i18n.global.t(e.subResource.resourceMetaTitle),
						resourceComponent:e.subResource.resourceComponent,
						component:dynamicImport(dynamicViewsModules, e.subResource.resourceComponent as string),
						meta: {
							// cache: false,
							title: e.subResource.resourceMetaTitle,
							isLink: '',
							isHide: e.subResource.resourceMetaIshide===0? false:true,
							isKeepAlive: e.subResource.resourceMetaIskeepaliv===0? false:true,
							isAffix: e.subResource.resourceMetaIsaffix===0? false:true,
							isIframe: e.subResource.resourceMetaIslframe===0? false:true,
							icon: e.subResource.resourceMetaIcon,
						},
						children:[]
					}
					if(e.sub2Resources.length>0){
						e.sub2Resources.forEach(su => {
							mu.children.push({
								id:su.id,
								resourceLevel:3,
								code:su.code,
								path: su.resourcePath,
								resourceSortOrder:su.resourceSortOrder,
								name: su.resourceName,
								title:i18n.global.t(su.resourceMetaTitle),
								resourceComponent:su.resourceComponent,
								component:dynamicImport(dynamicViewsModules, su.resourceComponent as string),
								meta: {
									// cache: false,
									title: su.resourceMetaTitle,
									isLink: '',
									isHide: su.resourceMetaIshide===0? false:true,
									isKeepAlive: su.resourceMetaIskeepaliv===0? false:true,
									isAffix: su.resourceMetaIsaffix===0? false:true,
									isIframe: su.resourceMetaIslframe===0? false:true,
									icon: su.resourceMetaIcon,
								}
							})
						});
					}
					mo.children.push(mu)
				});	
			}
			list.push(mo)
		});
	}
	else{
		routes.forEach((el,index) => {	
			if(store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===el.mainResource.code)===-1){
				return
			}
			const m1=store.state.userInfos.userInfos.meuns[store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===el.mainResource.code)]
			const mo={
				id:el.mainResource.id,
				resourceLevel:1,
				code:el.mainResource.code,
				path: el.mainResource.resourcePath,
				resourceSortOrder:el.mainResource.resourceSortOrder,
				name: el.mainResource.resourceName,
				title:i18n.global.t(el.mainResource.resourceMetaTitle),
				resourceComponent:el.mainResource.resourceComponent,
				redirect:el.mainResource.resourceRedirect,
				component:dynamicImport(dynamicViewsModules, el.mainResource.resourceComponent as string),
				meta: {
					grantPrivilege:m1.grantPrivilege,
					cache: false,
					title: el.mainResource.resourceMetaTitle,
					isLink: '',
					isHide: el.mainResource.resourceMetaIshide===0? false:true,
					isKeepAlive: el.mainResource.resourceMetaIskeepalive===0? false:true,
					isAffix: el.mainResource.resourceMetaIsaffix===0? false:true,
					isIframe: el.mainResource.resourceMetaIslframe===0? false:true,
					icon: el.mainResource.resourceMetaIcon,
				},
				children:[]
			}
			if(el.subResources.length>0){
				
				el.subResources.forEach((e,i) => {
					if(store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===e.subResource.code)===-1){
						return
					}
					const m2=store.state.userInfos.userInfos.meuns[store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===e.subResource.code)]
					let mu={
						id:e.subResource.id,
						resourceLevel:2,
						code:e.subResource.code,
						path: e.subResource.resourcePath,
						resourceSortOrder:e.subResource.resourceSortOrder,
						name: e.subResource.resourceName,
						title:i18n.global.t(e.subResource.resourceMetaTitle),
						resourceComponent:e.subResource.resourceComponent,
						component:dynamicImport(dynamicViewsModules, e.subResource.resourceComponent as string),
						meta: {
							grantPrivilege:m2.grantPrivilege,
							cache: false,
							title: e.subResource.resourceMetaTitle,
							isLink: '',
							isHide: e.subResource.resourceMetaIshide===0? false:true,
							isKeepAlive: e.subResource.resourceMetaIskeepaliv===0? false:true,
							isAffix: e.subResource.resourceMetaIsaffix===0? false:true,
							isIframe: e.subResource.resourceMetaIslframe===0? false:true,
							icon: e.subResource.resourceMetaIcon,
						},
						children:[]
					}
					if(e.sub2Resources.length>0){
						e.sub2Resources.forEach(su => {
							if(store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===su.code)===-1){
								return
							}
							const m3=store.state.userInfos.userInfos.meuns[store.state.userInfos.userInfos.meuns.findIndex(m=>m.resourceCode===su.code)]
							mu.children.push({
								id:su.id,
								resourceLevel:3,
								code:su.code,
								path: su.resourcePath,
								resourceSortOrder:su.resourceSortOrder,
								name: su.resourceName,
								title:i18n.global.t(su.resourceMetaTitle),
								resourceComponent:su.resourceComponent,
								component:dynamicImport(dynamicViewsModules, su.resourceComponent as string),
								meta: {
									grantPrivilege:m3.grantPrivilege,
									cache: false,
									title: su.resourceMetaTitle,
									isLink: '',
									isHide: su.resourceMetaIshide===0? false:true,
									isKeepAlive: su.resourceMetaIskeepaliv===0? false:true,
									isAffix: su.resourceMetaIsaffix===0? false:true,
									isIframe: su.resourceMetaIslframe===0? false:true,
									icon: su.resourceMetaIcon,
								}
							})
						});
					}
					mo.children.push(mu)
				});	
			}
			list.push(mo)
		});
	}
	}
	
	// return mm
	return list;
}

/**
 * 后端路由 component 转换函数
 * @param dynamicViewsModules 获取目录下的 .vue、.tsx 全部文件
 * @param component 当前要处理项 component
 * @returns 返回处理成函数后的 component
 */
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {
	const keys = Object.keys(dynamicViewsModules);
	const matchKeys = keys.filter((key) => {
		const k = key.replace(/..\/views|../, '');
		return k.startsWith(`${component}`) || k.startsWith(`/${component}`);
	});
	if (matchKeys?.length === 1) {
		const matchKey = matchKeys[0];
		return dynamicViewsModules[matchKey];
	}
	if (matchKeys?.length > 1) {
		return false;
	}
}
