import {
	getToken,
	setToken,
	removeToken
} from './auth'
import {
	setVersion
} from '../utils/version.js'
import {
	getBaseUrl
} from '../utils/version.js'

let baseURL;
setVersion()

let isRefreshing = false
let subscribers = []

// 订阅 Token 刷新
function subscribeTokenRefresh(cb) {
	subscribers.push(cb)
}

// 发布 Token 刷新完成
function onRrefreshed(token) {
	subscribers.forEach(cb => cb(token))
	subscribers = []
}

// 请求拦截器
const requestInterceptor = (options) => {
	// 获取token
	const token = uni.getStorageSync('accessToken')
	if (token) {
		options.header = {
			...options.header,
			'Authorization': `Bearer ${token}`
		}
	}

	// #ifdef H5
	// H5端跨域处理
	options.header = {
		...options.header,
		'Access-Control-Allow-Origin': '*'
	}
	// #endif

	return options
}

// 响应拦截器 
const responseInterceptor = async (options, response, resolve, reject) => {
	const {
		statusCode,
		data
	} = response
	// 请求成功
	if (statusCode >= 200 && statusCode < 300) {
		return data
	}

	// 处理错误
	if (statusCode === 401) {

		return await handleUnauthorized(options, resolve, reject)
	}

	// 其他错误
	uni.showToast({
		title: data.message || '请求失败',
		icon: 'none'
	})
	return Promise.reject(data)
}
// 创建 uni.request 的封装
// const request = (options) => {
//   return new Promise((resolve, reject) => {
//     uni.request({
//       ...options,
//       success: (res) => {
//         if (res.statusCode === 401) {
//           // 处理 401 逻辑
//           handleUnauthorized(options, resolve, reject)
//         } else {
//           resolve(res)
//         }
//       },
//       fail: (err) => {
//         reject(err)
//       }
//     })
//   })
// }

// 请求方法
const request = async (options, isUpdate) => {
	// 合并配置
	let url = uni.getStorageSync('baseUrl')
	if (uni.getStorageSync('setVersion').VersionCode == '') {
		setVersion()
	}

	if (!url) {
		await new Promise((resolve, reject) => {
			uni.request({
				url: 'https://api.mrrwlkj.top/api/openPuc/getSjApiUrl', // 接口地址
				method: 'GET', // 请求方法（默认 GET）
				header: {
					'Content-Type': 'application/json', // 请求头
					'VersionCode': uni.getStorageSync('setVersion').VersionCode,
					'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand,
					'DeviceType': uni.getStorageSync('setVersion').DeviceType
				},
				success: (res) => {
					if (res.data.code == 200) {
						uni.setStorageSync('baseUrl', res.data.data.url)
						url = res.data.data.url
						resolve(url)
					}
					console.log('请求成功', res.data);
				},
				fail: (err) => {
					console.log('请求失败', err);
				},
				complete: () => {
					console.log('请求完成（无论成功失败都会执行）');
				}
			});
		})

	}



	if (process.env.NODE_ENV === 'development') {
		baseURL = url; // 发布到生产环境时，此处代码会被摇树移除掉。	
		baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时，此处代码会被摇树移除掉。
		//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时，此处代码会被摇树移除掉。
		//baseURL = 'https://app.mrrweb.com.cn';
	} else {
		baseURL = url; // 发布到生产环境时，此处代码会被摇树移除掉。
		baseURL = 'http://60.247.146.5:93'; // 发布到生产环境时，此处代码会被摇树移除掉。	
			//baseURL = 'http://60.247.146.5:96'; // 发布到生产环境时，此处代码会被摇树移除掉。
		//baseURL = 'https://app.mrrweb.com.cn';

		console.log('生产环境');
	}

	// 基础配置
	const config = {
		baseURL: baseURL, // APP和H5的开发URL
		baseURL: baseURL, // APP和H5的开发URL
		// baseURL: 'https://app.mrrweb.com.cn', // APP和H5的生产URL

		header: {
			'content-type': 'application/json',
			'VersionCode': uni.getStorageSync('setVersion').VersionCode,
			'DeviceBrand': uni.getStorageSync('setVersion').DeviceBrand,
			'DeviceType': uni.getStorageSync('setVersion').DeviceType
		},
		timeout: 60000 // 超时时间
	}


	options = {
		...config,
		...options,
		url: !isUpdate ? `${config.baseURL}${options.url}` : options.url
	}


	// 请求拦截
	options = requestInterceptor(options)

	// 发起请求
	return new Promise((resolve, reject) => {
		// #ifdef H5
		// H5端添加loading
		if (!options.hideLoading) {
			uni.showLoading({
				title: '加载中...'
			})
		}
		// #endif

		uni.request({
			...options,
			success: (res) => {
				// #ifdef H5
				if (!options.hideLoading) {
					uni.hideLoading()
				}
				// #endif
				resolve(responseInterceptor(options, res, resolve, reject))
			},
			fail: (err) => {
				// #ifdef H5
				if (!options.hideLoading) {
					uni.hideLoading()
				}
				// #endif

				// 网络错误处理
				let errorMsg = '网络错误，请稍后重试'
				// #ifdef H5
				if (err.errMsg.includes('timeout')) {
					errorMsg = '请求超时，请检查网络'
				}
				// #endif

				uni.showToast({
					title: errorMsg,
					icon: 'none'
				})
				reject(err)
			}
		})
	})
}
// 处理 401 未授权
async function handleUnauthorized(originalRequest, resolve, reject) {
	if (!getToken()) {
		return redirectToLogin()
	}
	// 如果正在刷新 Token，将请求加入队列
	if (isRefreshing) {
		return subscribeTokenRefresh(token => {
			originalRequest.header['Authorization'] = `Bearer ${token}`
			request(originalRequest, true).then(resolve).catch(reject)
		})
	}

	isRefreshing = true

	try {
		const newToken = await refreshToken()
		setToken(newToken)
		onRrefreshed(newToken)

		// 用新 Token 重试原始请求
		originalRequest.header['Authorization'] = `Bearer ${newToken}`
		const response = await request(originalRequest, true)
		// resolve(response)
		return response
	} catch (error) {
		removeToken()
		redirectToLogin()
		// reject(error)
		return error
	} finally {
		isRefreshing = false
	}
}

// 刷新 Token
async function refreshToken() {
	const refreshToken = uni.getStorageSync('refreshToken')
	if (!refreshToken) {
		throw new Error('No refresh token')
	}
	const res = await request({
		url: '/sj/refreshtoken',
		data: {
			refresh_token: uni.getStorageSync('refreshToken'),
			deviceid: getApp().globalData.deviceid
		},
		method: 'POST'
	})

	if (res.state == 1 || res.code == 200) {
		uni.setStorageSync('accessToken', res.access_token)
		uni.setStorageSync('refreshToken', res.refresh_token)
		return res.access_token
	}

	throw new Error('Refresh token failed')
}

// 跳转到登录页
function redirectToLogin() {
	// uni.reLaunch({
	// 	url: '/pages/login/login'
	// })
	//一键登录测试
	// uni.oprPresentLogin()
	uni.navigateTo({
		url: '/pages/blogPopup/blogPopup'
	});
}

// 导出请求方法
export default {
	// GET请求
	get(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'GET',
			...options
		})
	},

	// POST请求
	post(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'POST',
			...options
		})
	},

	// PUT请求
	put(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'PUT',
			...options
		})
	},

	// DELETE请求
	delete(url, data = {}, options = {}) {
		return request({
			url,
			data,
			method: 'DELETE',
			...options
		})
	}
}