import axios from 'axios';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
import { ElMessage } from 'element-plus';
import { endsWith } from 'lodash-es';
import { storage } from '/@/cool/utils';
import { useBase } from '/$/base';
import { router } from '../router';
import { config, isDev } from '/@/config';

// 创建 axios 实例
const request = axios.create({
	timeout: import.meta.env.VITE_TIMEOUT, // 设置请求超时时间
	withCredentials: false // 不携带凭证
});

// 配置 NProgress
NProgress.configure({
	showSpinner: true // 显示加载指示器
});

// 请求队列，用于存储待处理的请求
let queue: Array<(token: string) => void> = [];

// 标识是否正在刷新 token
let isRefreshing = false;

// 请求拦截器
request.interceptors.request.use(
	(req: any) => {
		const { user } = useBase(); // 获取用户信息

		if (req.url) {
			// 控制请求进度条的显示
			if (
				!config.ignore.NProgress.some(e => req.url.match(new RegExp(`${e}.*`))) &&
				(req.NProgress ?? true)
			) {
				NProgress.start();
			}
		}

		// 在开发环境中打印请求信息
		if (isDev) {
			console.group(req.url);
			console.log('method:', req.method);
			console.table('data:', req.method == 'get' ? req.params : req.data);
			console.groupEnd();
		}

		if (!req.headers) {
			req.headers = {};
		}

		// 设置请求头中的语言
		if (req.headers['language'] !== null) {
			req.headers['language'] = config.i18n.locale;
		}

		// 验证 token
		if (user.token) {
			// 设置请求头中的 Authorization
			if (req.headers['Authorization'] !== null) {
				req.headers['Authorization'] = user.token;
			}

			// 忽略特定请求
			if (['eps', 'refreshToken'].some(e => endsWith(req.url, e))) {
				return req;
			}

			// 判断 token 是否过期
			if (storage.isExpired('token')) {
				// 判断 refreshToken 是否过期
				if (storage.isExpired('refreshToken')) {
					ElMessage.error('登录状态已失效，请重新登录');
					user.logout();
				} else {
					// 如果不在刷新中，则刷新 token
					if (!isRefreshing) {
						isRefreshing = true;

						user.refreshToken()
							.then(token => {
								queue.forEach(cb => cb(token)); // 处理队列中的请求
								queue = [];
								isRefreshing = false;
							})
							.catch(() => {
								user.logout();
							});
					}

					// 返回一个新的 Promise，等待 token 刷新完成
					return new Promise(resolve => {
						queue.push(token => {
							if (req.headers) {
								req.headers['Authorization'] = token; // 重新设置 token
							}
							resolve(req);
						});
					});
				}
			}
		}

		return req;
	},
	error => {
		return Promise.reject(error); // 请求错误处理
	}
);

// 响应拦截器
request.interceptors.response.use(
	res => {
		NProgress.done(); // 结束进度条

		if (!res?.data) {
			return res;
		}

		const { code, data, message } = res.data;

		if (!code) {
			return res.data; // 返回数据
		}

		switch (code) {
			case 1000:
				return data; // 成功返回数据
			default:
				return Promise.reject({ code, message }); // 处理错误
		}
	},
	async error => {
		NProgress.done(); // 结束进度条

		if (error.response) {
			const { status } = error.response;
			const { user } = useBase();

			if (status == 401) {
				user.logout(); // 未授权，登出用户
			} else {
				if (!isDev) {
					switch (status) {
						case 403:
							router.push('/403'); // 禁止访问
							break;

						case 500:
							router.push('/500'); // 服务器错误
							break;

						case 502:
							router.push('/502'); // 网关错误
							break;
					}
				}
			}
		}

		return Promise.reject({ message: error.response?.data?.message || error.message }); // 返回错误信息
	}
);

export { request };
