import Axios, { AxiosRequestConfig } from 'axios';
import storage from './storage';
const prefix = '/api';
const refreshTokenCodes = 10009;
const logOutCode = 10010;
const SUCCESS_CODE = 0;
let token = '';

const instance = Axios.create({
	baseURL: prefix,
});
/**
 * @description 刷新token
 */
const refreshToken = () => {
	const { value } = storage.getItme('refresh_token');
	return instance({
		url: '/v1/token_refresh',
		method: 'PUT',
		headers: {
			token: value,
		},
	}).then((data: any) => {
		token = '';
		storage.setItem('token', data);
		return data;
	});
};
let isRefreshing = false;
let cacheRequests: any[] = [];
// 请求拦截
instance.interceptors.request.use((requestConfig) => {
	// const sessionToken = sessionStorage.getItem('token');
	const { value, sucess } = storage.getItme('token');
	return {
		...requestConfig,
		params: {
			...requestConfig.params,
			random: Math.random(),
		},
		headers: {
			token: sucess ? value : '',
			...requestConfig.headers,
		},
	};
});
/**
 * @description 拦截响应
 */
instance.interceptors.response.use(
	(response) => {
		// 如果需要刷新token
		if (response.data.code === refreshTokenCodes) {
			if (!isRefreshing) {
				isRefreshing = true;
				return refreshToken()
					.then((data) => {
						sessionStorage.setItem('token', data);
						cacheRequests.forEach((cb) => cb(data));
						cacheRequests = [];

						return instance({
							...response.config,
							headers: { ...response.config.headers, token: data },
						});
					})
					.finally(() => {
						isRefreshing = false;
					});
			} else {
				// 如果正在刷新token 则需要缓存这个请求
				return new Promise((resolve) => {
					cacheRequests.push((token) => {
						resolve(
							instance({
								...response.config,
								headers: { ...response.config.headers, token: token },
							})
						);
					});
				});
			}
		}
		// 如果是需要退出
		if (response.data.code === logOutCode) {
			localStorage.clear();
			window.location.href = '/login';
			return Promise.reject(response.data);
		}
		// 请求成功
		if (response.data.code === SUCCESS_CODE) {
			return Promise.resolve(response.data.data);
		} else {
			return Promise.reject(response.data);
		}
	},
	(error) => Promise.reject(error)
);
export default {
	sendRequest: (config: AxiosRequestConfig) => {
		return instance(config);
	},
	instance,
};
