// 运行时配置

// 全局初始化数据配置，用于 Layout 用户信息和权限初始化
// 更多信息见文档：https://umijs.org/docs/api/runtime-config#getinitialstate
import { VersionChecker } from '@/components';
import Avatar from '@/layout/guide/Avatar';
import { auth } from '@/services';
import { Navigate } from '@@/exports';
import { RunTimeLayoutConfig } from '@@/plugin-layout/types';
import { RequestConfig } from '@@/plugin-request/request';
import { InfoCircleFilled } from '@ant-design/icons';
import { LeftMenu } from '@chageable/components';
import '@nutui/nutui-react/dist/style.scss';
import { history } from '@umijs/max';
import { Alert, Button, message, notification, Spin } from 'antd';
import React from 'react';
import './global.less';

interface InitialStateProps {
	currentUser?: AuthAPI.UserVO;
	currentAdmin?: AuthAPI.AdminVO;
	platformId: string;
	channel?: AuthAPI.ChannelVO;
	tip: any;
}

// 动态导入组件
function dynamicImport(componentPath: string) {
	const Component = React.lazy(() => {
		// 处理不同的组件路径格式
		const path = componentPath.startsWith('@/')
			? componentPath.replace('@/', '')
			: componentPath;

		return new Promise((resolve) => {
			import(`@/pages/${path}`)
				.then((module) => resolve(module))
				.catch((reason) => {
					console.log('组件加载异常', reason);
					resolve(import(`@/pages/404` as string));
				}); // 处理查找兜底，需要对应路径下有404兜底组件
		});
	});

	return (
		<React.Suspense fallback={<Spin />}>
			<Component />
		</React.Suspense>
	);
}

// 路由转换函数
function transformTreeRoutes(serverRoutes: any[], parentId = ''): any[] {
	return serverRoutes.map((route) => {
		const umiRoute: any = {
			id: route.menuId,
			path: route.path,
			parentId,
			name: route.name,
			icon: route.icon,
			access: route.access,
			hideInMenu: route.hideInMenu,
		};

		// 处理组件
		if (route.component) {
			try {
				umiRoute.element = dynamicImport(route.component);
			} catch (e) {
				console.log('组件加载异常', e);
				umiRoute.element = dynamicImport('@page/404');
			}
		}

		// 处理子路由
		if (route.routes?.length) {
			umiRoute.children = transformTreeRoutes(
				route.routes,
				route.menuId,
			).filter((r) => !(r?.path === ' ') && r.hideInMenu === false);
			if (umiRoute.children[0]?.path) {
				umiRoute.children.unshift({
					path: route.path,
					element: <Navigate to={umiRoute.children[0]?.path} replace />,
				});
			}
		}

		return umiRoute;
	});
}

// 动态路由缓存（改为函数内部变量）
let cachedRoutes: any[] = [];
let cachedMenus: any[] = [];

export async function patchClientRoutes({ routes }: { routes: any[] }) {
	try {
		// 转换路由结构
		const root = routes.find((r) => r.path === '/');

		root.children.push(...cachedRoutes);
		root.children.unshift({
			path: '/',
			element: <Navigate to={root.children[1].path} replace />,
		});
	} catch (error) {
		console.error('Failed to load dynamic routes:', error);
		history.push('/404');
	}
}

// 拦截路由渲染，比如做一些权限校验
export const render = async (oldRender: () => void) => {
	// 如果已有缓存，直接使用
	if (cachedRoutes.length > 0) {
		oldRender();
		return;
	}

	const { data: employeeVO } = await auth.user.userEmployee({
		employeeShowQry: {},
	});

	let platformId = '1769220738064285698';
	let roleIdList: string[] = [];

	if (employeeVO) {
		window.localStorage.setItem('employee', JSON.stringify(employeeVO));

		const userRoleVOList = employeeVO.userRoleList?.filter(
			(item) => item.platformId === platformId,
		);

		if (!userRoleVOList?.length) {
			message.error('请先绑定角色');
			window.localStorage.removeItem('employee');
			window.localStorage.removeItem('admin');
			window.localStorage.removeItem('roleSlug');
			// 未登录，跳转到登录页面
			window.location.href =
				process.env.UMI_APP_SSO_LOGIN_URL +
				encodeURIComponent(process.env.UMI_APP_OPERATION_URL || '');
			return;
		}

		window.localStorage.setItem(
			'userRoleVOList',
			JSON.stringify(userRoleVOList),
		);

		// 根据 localStorage 判断有没有选择角色，如果没有选择则默认选择第一个
		if (!window.localStorage.getItem('roleSlug')) {
			window.localStorage.setItem('roleSlug', userRoleVOList?.[0]?.slug);
			roleIdList = [userRoleVOList?.[0]?.roleId];
		} else {
			const roleSlug = window.localStorage.getItem('roleSlug');
			const role = userRoleVOList?.find((item) => item.slug === roleSlug);

			if (!role) {
				message.error('请先绑定角色');
				window.localStorage.removeItem('employee');
				window.localStorage.removeItem('admin');
				window.localStorage.removeItem('roleSlug');
				// 未登录，跳转到登录页面
				window.location.href =
					process.env.UMI_APP_SSO_LOGIN_URL +
					encodeURIComponent(process.env.UMI_APP_OPERATION_URL || '');
				return;
			}

			roleIdList = [role?.roleId];
		}
	} else {
		const { data: adminVO } = await auth.user.userAdmin({
			adminShowQry: {},
		});

		window.localStorage.setItem('admin', JSON.stringify(adminVO));
		window.localStorage.setItem(
			'userRoleVOList',
			JSON.stringify([]),
		);
		window.localStorage.setItem('roleSlug', 'operation');
	}

	// 获取服务端路由配置
	await auth.user
		.userMenu({
			roleMenuTreeQry: {
				platformId: platformId,
				roleId: roleIdList,
			},
		})
		.then(({ data: serverRoutes }) => {
			cachedMenus = serverRoutes as any[];
			cachedRoutes = transformTreeRoutes(
				serverRoutes || [],
				'ant-design-pro-layout',
			);
			oldRender();
		});
};

export async function getInitialState(): Promise<InitialStateProps> {
	let current: any;

	const { data: channel } = await auth.channel.selectChannelByDomain({
		domain: 'operation.erp.qilincloud168.com',
	});

	// 根据 localStorage 获取当前用户信息 admin 和 employee
	const adminVO = JSON.parse(window.localStorage.getItem('admin') || '{}');
	const employeeVO = JSON.parse(
		window.localStorage.getItem('employee') || '{}',
	);

	current = {
		channel,
		platformId: '1769220738064285698',
		currentUser: {
			...employeeVO,
			...adminVO,
		},
	};

	return current;
}

export const layout: RunTimeLayoutConfig = ({ initialState }) => {
	const link =
		document.querySelector("link[rel*='icon']") ||
		document.createElement('link');
	//@ts-ignore
	link.type = 'image/x-icon';
	//@ts-ignore
	link.rel = 'shortcut icon';
	//@ts-ignore
	link.href = initialState?.channel?.logo;
	document.getElementsByTagName('head')[0].appendChild(link);

	return {
		title: initialState?.channel?.title,
		subTitle: initialState?.channel?.subTitle,
		logo: initialState?.channel?.logo,
		menuRender: (props, defaultDom) => {
			if (props.isMobile) {
				return defaultDom;
			}

			const menuData = props.menuData;

			if (!menuData) {
				return defaultDom;
			}

			return (
				<LeftMenu
					menuData={menuData}
					pathname={history.location.pathname}
					onClick={(item) => {
						history.push(item.key as string);
					}}
				/>
			);
		},
		menu: {
			type: 'group',
			locale: false,
			request: async () => cachedMenus,
		},
		fixedHeader: true,
		// links: false,
		layout: 'mix',
		navTheme: 'light',
		// splitMenus: true,
		contentWidth: 'Fluid',
		siderWidth: 134,
		// siderMenuType: 'inline',
		hasPageContainer: 1,
		token: {
			header: {
				heightLayoutHeader: initialState?.tip?.show ? 108 : 56,
			},
		},
		avatarProps: {
			src: initialState?.currentUser?.avatar,
			size: 'small',
			title: initialState?.currentUser?.name,
			render: (props, dom) => {
				return <Avatar>{dom}</Avatar>;
			},
		},
		onPageChange: () => {
			// if (!initialState?.currentUser) {
			// 	// 未登录，跳转到登录页面
			// 	window.location.href =
			// 		process.env.UMI_APP_SSO_LOGIN_URL +
			// 		encodeURIComponent(process.env.UMI_APP_OPERATION_URL || '');
			// }
		},
		// actionsRender: (props) => {
		// 	if (props.isMobile) return [];
		// 	if (typeof window === 'undefined') return [];
		// 	return [
		// 		props.layout !== 'side' && document.body.clientWidth > 1400 ? (
		// 			<SearchInput key={'SearchInput'} />
		// 		) : undefined,
		// 		<InfoCircleFilled key="InfoCircleFilled" />,
		// 		<QuestionCircleFilled key="QuestionCircleFilled" />,
		// 		<NotificationFilled key="NotificationFilled" />,
		// 	];
		// },
		headerRender: (props, defaultDom) => {
			return (
				<>
					<VersionChecker />
					{initialState?.tip?.show && (
						<Alert
							message={
								<div
									style={{
										color: 'white',
									}}
								>
									本网站提供的部分服务在你当前浏览器中无法使用，建议你更换为
									Chrome 浏览器查看本网站。
								</div>
							}
							icon={
								<InfoCircleFilled
									style={{
										color: 'white',
									}}
								/>
							}
							banner
							style={{
								backgroundColor: 'black',
							}}
							action={
								<Button
									type="text"
									style={{
										color: 'white',
									}}
								>
									查看详情
								</Button>
							}
						/>
					)}

					{React.cloneElement(defaultDom as any, {
						style: {
							height: '56px',
							lineHeight: '56px',
						},
					})}
				</>
			);
		},
		footerRender: () => {
			return <></>;
		},
		// menuExtraRender: (props) => {
		// 	if (props.isMobile) {
		// 		return <StoreSelect />;
		// 	}
		// },
		menuFooterRender: (props) => {
			if (props?.collapsed) return undefined;
			return (
				<p
					style={{
						textAlign: 'center',
						color: 'rgba(0,0,0,0.6)',
						paddingBlockStart: 12,
					}}
				>
					{initialState?.channel?.title} 提供技术支持
				</p>
			);
		},
	};
};

// 错误处理方案： 错误类型
enum ErrorShowType {
	SILENT = 0,
	WARN_MESSAGE = 1,
	ERROR_MESSAGE = 2,
	NOTIFICATION = 3,
	REDIRECT = 9,
}

// 与后端约定的响应数据格式
interface ResponseStructure {
	success: boolean;
	data: any;
	errCode?: string;
	errMessage?: string;
	showType?: ErrorShowType;
}

// 运行时配置
export const request: RequestConfig = {
	// 统一的请求设定
	timeout: 60000,
	headers: {
		'X-Requested-With': 'XMLHttpRequest',
		'Xh-Platform-Id': '1769220738064285698',
	},
	// 错误处理： umi@3 的错误处理方案。
	errorConfig: {
		// 错误抛出
		errorThrower: (res: ResponseStructure) => {
			const { success, data, errCode, errMessage, showType } = res;
			if (!success) {
				if (errCode === '401' || errCode === '403') {
					window.localStorage.removeItem('employee');
					window.localStorage.removeItem('admin');
					window.localStorage.removeItem('roleSlug');
					// 未登录，跳转到登录页面
					window.location.href =
						process.env.UMI_APP_SSO_LOGIN_URL +
						encodeURIComponent(process.env.UMI_APP_OPERATION_URL || '');
					return;
				}

				if (errCode === '400') {
					message.error(errMessage);
					return;
				}

				if (errCode === 'UNKNOWN_ERROR') {
					message.error('未知的错误');
					return;
				}

				const error: any = new Error(errMessage || errCode);
				error.name = 'BizError';
				error.info = { errCode, errMessage, showType, data };
				throw error; // 抛出自制的错误
			}
		},
		// 错误接收及处理
		errorHandler: (error: any, opts: any) => {
			if (opts?.skipErrorHandler) throw error;
			// 我们的 errorThrower 抛出的错误。
			if (error.name === 'BizError') {
				const errorInfo: ResponseStructure | undefined = error.info;
				if (errorInfo) {
					const { errMessage, errCode } = errorInfo;
					switch (errorInfo.showType) {
						case ErrorShowType.SILENT:
							// do nothing
							break;
						case ErrorShowType.WARN_MESSAGE:
							message.warning(errMessage);
							break;
						case ErrorShowType.ERROR_MESSAGE:
							message.error(errMessage);
							break;
						case ErrorShowType.NOTIFICATION:
							notification.open({
								description: errMessage,
								message: errCode,
							});
							break;
						case ErrorShowType.REDIRECT:
							// TODO: redirect
							break;
						default:
							message.error(errMessage);
					}
				}
			} else if (error.response) {
				// Axios 的错误
				// 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
				message.error(`Response status:${error.response.status}`);
			} else if (error.request) {
				// 请求已经成功发起，但没有收到响应
				// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
				// 而在node.js中是 http.ClientRequest 的实例
				message.error('None response! Please retry.1');
			} else {
				// 发送请求时出了点问题
				message.error('Request error, please retry.2');
			}
		},
	},

	// 请求拦截器
	requestInterceptors: [
		(
			url: any,
			options: {
				headers: any;
			},
		) => {
			const roleSlug = window.localStorage.getItem('roleSlug');

			if (roleSlug) {
				options.headers = {
					...options.headers,
					'Xh-Role-Slug': roleSlug,
				};
			}

			console.debug('请求拦截器', url, options);
			const apiUrl = '/api' + url;

			return {
				url: apiUrl,
				options,
			};
		},
	],

	// 响应拦截器
	responseInterceptors: [
		(response: ResponseStructure) => {
			// 拦截响应数据，进行个性化处理
			return response;
		},
	],
} as any;
