/**
 *  Copyright [2022] [https://www.xiaonuo.vip]
 *	Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *	1.请不要删除和修改根目录下的LICENSE文件。
 *	2.请不要删除和修改Snowy源码头部的版权声明。
 *	3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 *	4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 *	5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 *	6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
import { createRouter, createWebHistory } from 'vue-router'
import { notification } from 'ant-design-vue'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import systemRouter from './systemRouter'
import { afterEach, beforeEach } from './scrollBehavior'
import whiteListRouters from './whiteList'
import portal from './portal'
import userRoutes from '@/config/route'
import tool from '@/utils/tool'
import fullPageTool from './fullPageTool'
import { cloneDeep } from 'lodash-es'
const modules = import.meta.glob('/src/views/**/**.vue')
import { globalStore, searchStore } from '@/store'

// 进度条配置
NProgress.configure({ showSpinner: false, speed: 500 })

// 系统特殊路由
const routes_404 = [
	{
		path: '/:pathMatch(.*)*',
		hidden: true,
		component: () => import('@/layout/other/404.vue')
	}
]
// 系统路由
const routes = [...systemRouter, ...whiteListRouters, ...routes_404]

const router = createRouter({
	history: createWebHistory(),
	routes
})

// 设置标题
// document.title = sysBaseConfig.SNOWY_SYS_NAME

// 判断是否已加载过动态/静态路由
const isGetRouter = ref(false)

// 白名单校验
const exportWhiteListFromRouter = (router) => {
	const res = []
	for (const item of router) res.push(item.path)
	return res
}
const whiteList = exportWhiteListFromRouter(whiteListRouters)

router.beforeEach(async (to, from, next) => {
	NProgress.start()
	const store = globalStore()

	const sysBaseConfig = tool.data.get('SNOWY_SYS_BASE_CONFIG') || store.sysBaseConfig
	// 动态标题
	document.title = to.meta.title
		? `${to.meta.title} - ${sysBaseConfig.SNOWY_SYS_NAME}`
		: `${sysBaseConfig.SNOWY_SYS_NAME}`

	// 过滤白名单
	if (whiteList.includes(to.path)) {
		next()
		// NProgress.done()
		return false
	}

	const token = tool.data.get('TOKEN')
	if (to.path === '/login') {
		// 当用户输入了login路由，将其跳转首页即可
		if (token) {
			next({
				path: '/'
			})
			return false
		}
		// 删除路由(替换当前layout路由)
		router.addRoute(routes[0])
		isGetRouter.value = false
		next()
		return false
	} else {
		if (token) {
			// 有token的时候才保存登录之前要访问的页面
			tool.data.set('LAST_VIEWS_PATH', to.fullPath)
		}
		fullPageTool.check(to)
	}
	if (!token) {
		next({
			path: '/login'
		})
		return false
	}
	// 整页路由处理
	if (to.meta.fullpage) {
		to.matched = [to.matched[to.matched.length - 1]]
	}
	// 加载动态/静态路由
	if (!isGetRouter.value) {
		const apiMenu = tool.data.get('MENU') || []
		if (apiMenu.length === 0) {
			// 创建默认模块，显示默认菜单
			apiMenu[0] = cloneDeep(userRoutes.module[0])
		}
		const childrenApiMenu = apiMenu[0].children
		apiMenu[0].children = [...(childrenApiMenu ? childrenApiMenu : []), ...userRoutes.menu]
		let menuRouter = filterAsyncRouter(apiMenu)
		menuRouter = flatAsyncRoutes(menuRouter)
		menuRouter.forEach((item) => {
			router.addRoute('layout', item)
		})

		const search_store = searchStore()
		search_store.init(menuRouter)
		isGetRouter.value = true
		next({ ...to, replace: true })
		return false
	}
	beforeEach(to, from)
	next()
})

router.afterEach((to, from) => {
	afterEach(to, from)
	NProgress.done()
})

router.onError((error) => {
	NProgress.done()
	notification.error({
		message: '路由错误',
		description: error.message
	})
})

// 入侵追加自定义方法、对象
router.getMenu = () => {
	let apiMenu = tool.data.get('MENU') || []
	// 增加固定路由
	if (apiMenu.length === 0) {
		// 创建默认模块，显示默认菜单
		apiMenu[0] = cloneDeep(userRoutes.module[0])
	}
	const childrenApiMenu = apiMenu[0].children
	apiMenu[0].children = [...(childrenApiMenu ? childrenApiMenu : []), ...userRoutes.menu]
	return filterUrl(apiMenu)
}

const filterUrl = (map) => {
	const newMap = []
	const traverse = (maps) => {
		maps &&
			maps.forEach((item) => {
				item.meta = item.meta ? item.meta : {}
				// 处理iframe
				if (item.meta.type === 'iframe') {
					item.path = `/${item.name}`
				}
				// 递归循环
				if (item.children && item.children.length > 0) {
					item.children = filterUrl(item.children)
				}
				newMap.push(item)
			})
	}
	traverse(map)
	return newMap
}

// 转换
const filterAsyncRouter = (routerMap) => {
	const accessedRouters = []
	routerMap.forEach((item) => {
		item.meta = item.meta ? item.meta : {}
		// 处理外部链接特殊路由
		if (item.meta.type === 'iframe') {
			item.meta.url = item.path
			item.path = `/${item.name}`
		}
		// MAP转路由对象
		const route = {
			path: item.path,
			name: item.name,
			meta: item.meta,
			redirect: item.redirect,
			children: item.children ? filterAsyncRouter(item.children) : null,
			component: loadComponent(item.component)
		}
		// console.log('看看', route)
		accessedRouters.push(route)
	})
	return accessedRouters
}
const loadComponent = (component) => {
	if (component) {
		if (component.includes('/')) {
			return modules[`/src/views/${component}.vue`]
		}
		return modules[`/src/views/${component}/index.vue`]
	} else {
		return () => import(/* @vite-ignore */ `/src/layout/other/empty.vue`)
	}
}

// 路由扁平化
const flatAsyncRoutes = (routes, breadcrumb = []) => {
	const res = []
	routes.forEach((route) => {
		const tmp = { ...route }
		if (tmp.children) {
			const childrenBreadcrumb = [...breadcrumb]
			childrenBreadcrumb.push(route)
			const tmpRoute = { ...route }
			tmpRoute.meta.breadcrumb = childrenBreadcrumb
			delete tmpRoute.children
			res.push(tmpRoute)
			const childrenRoutes = flatAsyncRoutes(tmp.children, childrenBreadcrumb)
			childrenRoutes.map((item) => {
				res.push(item)
			})
		} else {
			const tmpBreadcrumb = [...breadcrumb]
			tmpBreadcrumb.push(tmp)
			tmp.meta.breadcrumb = tmpBreadcrumb
			res.push(tmp)
		}
	})
	return res
}

export default router
