import {
	requestConfig
} from '@/app.config.js'
let isRefreshing = true // 是否正在刷新的标记
let subscribers = []; // 缓存

function onAccessTokenFetched() {
	// 更新个人中心的数据
	uni.$emit("userinfoRefresh", true)
	subscribers.forEach((callback) => {
		callback()
	})
	subscribers = [];
}

function addSubscriber(callback) {
	subscribers.push(callback)
}

function checkStatus(param) {
	// 刷新token的函数,这需要添加一个开关，防止重复请求
	if (isRefreshing) {
		referToken()
	}
	isRefreshing = false;
	// 将token刷新成功后的回调请求缓存
	const retryOriginalRequest = new Promise((resolve) => {
		addSubscriber(() => {
			resolve(Request.prototype.http(param))
		})
	});
	return retryOriginalRequest;
}

// 无感刷新
function referToken() {
	uni.removeStorageSync('token');

	api.login({
		grant_type: 'refresh',
		refresh_token: uni.getStorageSync('refresh_token'),
		client_type: 0,
	}).then(res => {
		if (res.code === 200) {
			uni.removeStorageSync('refresh_token');

			uni.setStorageSync("token", 'Bearer ' + res.data
				.access_token);
			uni.setStorageSync("refresh_token", res.data
				.refresh_token);
			//执行缓存中的请求
			onAccessTokenFetched()
			//延迟几秒再将刷新token的开关放开，不然偶尔还是会重复提交刷新token的请求
			setTimeout(() => {
				isRefreshing = true;
			}, 3000)

		}
	})
}

class Request {
	http(param) {
		let url = param.url,
			header = param.header,
			method = param.method,
			data = param.data,
			dataType = 'json',
			responseType = param.responseType || 'text'
		if (header) {
			header = param.header
		} else {
			header = {
				'Content-type': "application/x-www-form-urlencoded",
			};
		}
		const token = uni.getStorageSync('token');
		header['token'] = header['token'] ? header['token'] : token ? token : '';
		// 返回promise
		return new Promise((resolve, reject) => {
			let baseUrl
			if (process.env.NODE_ENV === 'production') {
				baseUrl = requestConfig.prodBaseUrl
			} else {
				baseUrl = requestConfig.test ? requestConfig.testBaseUrl : requestConfig.devBaseUrl
			}
			// 请求
			uni.request({
				url: baseUrl + url,
				data: data,
				method: method,
				dataType: dataType,
				responseType: responseType,
				header: header,
				success: (res) => {
					if (res.statusCode && res.statusCode != 200) {
						uni.$u.toast("api错误" + res.data.error)
						return;
					}
					if (res.data.code !== 200) {
						// code判断:200成功,不等于200错误
						if (res.data.code == 501) {
							if (!uni.getStorageSync('refresh_token')) {
								webUni.webViewuni.reLaunch({
									url: "/pages/index/login/login",
								});
							}
							// 登录信息失效,静默登录
							checkStatus(param).then(res => {
								resolve(res)
							})

						} else {
							uni.$u.toast(res.data.msg)
						}
					}
					// 将结果抛出
					resolve(res.data)
				},
				//请求失败
				fail: (e) => {
					uni.$u.toast('网络异常, 请检查网络连接')
					resolve(e.data);
				},
				//请求完成
				complete() {
					resolve();
					return;
				},

			})
		})

	}
}
export default new Request()