import { ElMessage } from 'element-plus';
import {
	createRouter,
	createRouterMatcher,
	createWebHashHistory,
	createWebHistory,
	type RouteRecordRaw
} from 'vue-router';
import { type Router, storage, module } from '/@/cool';
import { isArray } from 'lodash-es';
import { useBase } from '/$/base';
import { Loading } from '../utils';
import { config, isDev } from '/@/config';

// 基本路径
const baseUrl = import.meta.env.BASE_URL;

// 扫描文件
const files = import.meta.glob(['/src/modules/*/{views,pages}/**/*', '!**/components']);

// 默认路由
const routes: RouteRecordRaw[] = [
	{
		path: '/',
		name: 'index',
		component: () => import('/$/base/pages/main/index.vue'),
		children: []
	},
	{
		path: '/:catchAll(.*)',
		name: '404',
		component: () => import('/$/base/pages/error/404.vue')
	}
];

// 创建路由器
const router = createRouter({
	history:
		config.app.router.mode == 'history'
			? createWebHistory(baseUrl)
			: createWebHashHistory(baseUrl),
	routes
}) as Router;

// 组件加载后
router.beforeResolve(() => {
	Loading.close();
});

let lock = false;

// 错误监听
router.onError((error: Error) => {
	if (!lock) {
		lock = true;

		// 显示错误信息
		ElMessage.error(`页面存在错误：${error.message}`);
		console.error(error);

		// 如果是动态加载模块失败的错误，且非开发环境，则刷新页面
		if (error.message?.includes('Failed to fetch dynamically imported module')) {
			if (!isDev) {
				window.location.reload();
			}
		}

		// 短暂延迟后解锁，允许后续错误处理
		setTimeout(() => {
			lock = false;
		}, 0);
	}
});

// 添加视图，页面路由
router.append = function (routeData) {
	if (!routeData) {
		return false; // 如果没有路由数据，直接返回
	}

	// 确保 routeData 是数组
	const routeList = isArray(routeData) ? routeData : [routeData];

	routeList.forEach(route => {
		if (!route.meta) {
			route.meta = {}; // 初始化 meta 对象
		}

		// 如果没有指定组件路径
		if (!route.component) {
			const viewPath = route.viewPath;

			if (viewPath) {
				if (viewPath.startsWith('http')) {
					// 如果是外部链接，使用 iframe 组件
					route.meta.iframeUrl = viewPath;
					route.component = () => import('/$/base/views/frame.vue');
				} else {
					// 从文件系统中动态导入组件
					route.component = files['/src/' + viewPath.replace('cool/', '')];
				}
			} else if (!route.redirect) {
				// 如果没有组件路径且没有重定向，默认重定向到 404
				route.redirect = '/404';
			}
		}

		// 支持 props 接收参数
		route.props = true;

		// 标记为动态添加的路由
		route.meta.dynamic = true;

		// 判断是页面还是视图，并添加到相应的路由
		if (route.isPage || route.viewPath?.includes('/pages/')) {
			router.addRoute(route);
		} else {
			router.addRoute('index', route);
		}
	});
};

// 删除路由
router.del = function (routeName) {
	const allRoutes = router.getRoutes();

	allRoutes.forEach(route => {
		if (route.name === routeName) {
			router.removeRoute(routeName); // 移除指定名称的路由
		}
	});
};

// 清空路由
router.clear = function () {
	const allRoutes = router.getRoutes();

	allRoutes.forEach(route => {
		if (route.name && route.meta?.dynamic) {
			router.removeRoute(route.name); // 移除所有动态添加的路由
		}
	});
};

// 找路由
router.find = function (path: string) {
	const { menu } = useBase();

	// 获取已注册的路由
	const registeredRoutes = router.getRoutes();

	// 构建路由列表，包括已注册的路由、菜单配置和模块自定义路由
	const routeList: any[] = [
		...registeredRoutes.map(route => ({
			...route,
			isReg: true
		})),
		...menu.routes,
		...module.list.flatMap(module => (module.views || []).concat(module.pages || []))
	];

	let isRegistered = false;
	let matchedRoute: (typeof routeList)[number] | undefined;

	// 创建路由匹配器
	const matcher = createRouterMatcher(routeList, {});

	// 查找匹配的路由
	matcher.getRoutes().find(route => {
		const routeRegex = new RegExp(route.re);

		if (routeRegex.test(path)) {
			if (path === '/') {
				// 如果路径是根路径，查找标记为首页的路由
				matchedRoute = routeList.find(route => route.meta?.isHome);
			} else {
				// 否则查找路径匹配且名称不是 'index' 的路由
				matchedRoute = routeList.find(
					r => r.path === route.record.path && r.name !== 'index'
				);
			}

			if (matchedRoute) {
				isRegistered = !!matchedRoute.isReg; // 检查路由是否已注册
			}

			return true;
		}
		return false;
	});

	return {
		route: matchedRoute,
		isReg: isRegistered
	};
};

// 路由守卫
router.beforeEach(async (to, from, next) => {
	// 等待应用配置加载完
	await Loading.wait();

	// 获取用户和进程数据
	const { user, process } = useBase();

	// 查找路由信息
	const { isReg, route } = router.find(to.path);

	// 如果路由不存在
	if (!route) {
		next(user.token ? '/404' : '/login'); // 根据用户登录状态重定向
		return;
	}

	// 如果路由未注册
	if (!isReg) {
		router.append(route); // 注册路由
		next(to.fullPath); // 重定向到原路径
		return;
	}

	// 如果用户已登录
	if (user.token) {
		if (to.path.includes('/login')) {
			// 如果在登录页且 Token 未过期，重定向到首页
			if (!storage.isExpired('token')) {
				next('/');
				return;
			}
		} else {
			process.add(to); // 添加路由进程
		}
	} else {
		// 清除用户信息
		user.clear();

		// 如果路径不在忽略 Token 验证的列表中，重定向到登录页
		if (!config.ignore.token.some(ignorePath => to.path === ignorePath)) {
			next('/login');
			return;
		}
	}

	next(); // 继续导航
});

export { router };
