/**
 * config 配置项说明
 * baseUrl = "", // 接口的根地址
 * tokenName = "Authorization", // 请求头中token的名字,与服务器端对应
 * loginTimeoutCode : "5000", // 登录超时或失效的情况下,服务器端返回的错误码
 * loginTimeoutPage = "/pages/login/index", // 登录超时或失效的情况下,跳转到的登录页面
 */
import config from '@/common/config.js'
import token from '@/utils/auth.token.js'

/**
 * request options配置项说明
 * url: '', // url	String	是		开发者服务器接口地址	
 * data: {}, // data	Object/String/ArrayBuffer	否		请求的参数	App 3.3.7 以下不支持 ArrayBuffer 类型
 * header: {}, // header	Object	否		设置请求的 header,header 中不能设置 Referer。	App、H5端会自动带上cookie,且H5端不可手动修改
 * method: 'GET', // method	String	否	GET	有效值详见下方说明	
 * timeout: 6000, // timeout	Number	否	60000	超时时间,单位 ms	H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
 * showLoading: true, // 是否显示加载等待框
 * loadingTitle: '加载中', // 加载等待框的提示文字
 * showFailMessage: true, // 返回失败信息是否显示
 * catchError: true, // 是否集中管理返回的success为false的情况,如果为false,在请求处判断code值做业务处理
 */
const request = (options, noLoading) => {
	let _opts = {
		url: '', // url	String	是		开发者服务器接口地址	
		data: {}, // data	Object/String/ArrayBuffer	否		请求的参数	App 3.3.7 以下不支持 ArrayBuffer 类型
		header: {}, // header	Object	否		设置请求的 header,header 中不能设置 Referer。	App、H5端会自动带上cookie,且H5端不可手动修改 {"content-type": "application/json"}
		method: 'GET', // method	String	否	GET	有效值详见下方说明	
		timeout: 60000, // timeout	Number	否	60000	超时时间,单位 ms	H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
		// dataType	String	否	json	如果设为 json,会尝试对返回的数据做一次 JSON.parse
		// responseType	String	否	text	设置响应的数据类型。合法值:text、arraybuffer	支付宝小程序不支持
		// sslVerify	Boolean	否	true	验证 ssl 证书	仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包
		// withCredentials	Boolean	否	false	跨域请求时是否携带凭证(cookies)	仅H5支持(HBuilderX 2.6.15+)
		// firstIpv4	Boolean	否	false	DNS解析时优先使用ipv4	仅 App-Android 支持 (HBuilderX 2.8.0+)
		// success	Function	否		收到开发者服务器成功返回的回调函数	
		// fail	Function	否		接口调用失败的回调函数	
		// complete	Function	否		接口调用结束的回调函数(调用成功、失败都会执行)
		showLoading: !noLoading, // 是否显示加载等待框
		loadingTitle: '加载中', // 加载等待框的提示文字
		showFailMessage: true, // 返回失败信息是否显示
		catchError: true, // 是否集中管理Catch,
	}
	Object.assign(_opts, options)
	let _token = token.getToken()
	console.log("token",_token)
	let _baseUrl = config.baseUrl
	let _tokenName = config.tokenName
	if (_tokenName) {
		_opts.header[_tokenName] = _token
	} else {
		_opts.header['satoken'] = _token
	}

	return new Promise((resolve, reject) => {
		if (_opts.showLoading) {
			uni.showLoading({
				title: _opts.loadingTitle || '加载中',
				mask: true
			})
		}
		return uni.request({
			url: (_baseUrl || '') + (_opts.url || ''),
			method: _opts.method,
			data: _opts.data || null,
			header: _opts.header,
			timeout: _opts.timeout || 60000,
			success: res => {
				if (200 === res.statusCode) {
					let data = res.data
					if (_opts.catchError) {
						if (data.success) {
							resolve(data.data)
						} else {
							let loginTimeoutCode = "5000"
							let loginTimeoutPage = "/pages/login/index"
							if (config.loginTimeoutCode) {
								loginTimeoutCode = "" + config.loginTimeoutCode
							}
							if (config.loginTimeoutPage) {
								loginTimeoutPage = config.loginTimeoutPage
							}
							if (loginTimeoutCode === data.code) {
								uni.showModal({
									title: '提示',
									content: '登录过期或失效,请重新登录!',
									showCancel: false,
									success: function(res) {
										uni.reLaunch({
											url: loginTimeoutPage
										})
									}
								});
							} else {
								if (_opts.showFailMessage) {
									uni.showToast({
										title: data.msg,
										icon: 'none',
										duration: 2000,
									})
								}
							}
							reject(data)
						}
					} else {
						resolve(data)
					}
				} else {
					let em = {
						"code": "404",
						"data": "",
						"msg": "网络请求失败~",
						"success": false,
						"timestamp": new Date().getTime()
					}
					if (res.data) {
						if (res.data.error) {
							if (res.data.path) {
								em.msg = res.data.path + res.data.error
							} else {
								em.msg = res.data.error
							}
						}
						if (res.data.status) {
							em.code = "" + res.data.status
						}
					}
					if (_opts.showFailMessage) {
						uni.showToast({
							title: em.msg,
							icon: 'none',
							duration: 2000,
						})
					}
					reject(em)
				}
			},
			fail: error => {
				console.log('request-fail: ', error)
				let em = {
					"code": "600",
					"data": "",
					"msg": "网络请求失败~",
					"success": false,
					"timestamp": new Date().getTime()
				}
				if (error.errMsg) {
					// em.msg = error.errMsg
				}
				if (_opts.showFailMessage) {
					uni.showToast({
						title: em.msg,
						icon: 'none',
						duration: 2000,
					})
				}
				reject(em)
			},
			complete() {
				if (_opts.showLoading) {
					uni.hideLoading()
				}
			}
		})
	})

}

const req = function(url, method = "GET", data = {}, header = {}, options = {}, noLoading) {
	let _opts = {
		url: url,
		method: method,
		data: data,
		header: header
	}
	Object.assign(options, _opts)
	return request(options, noLoading)
}

const get = function(url, data = {}, header = {}, options = {}, noLoading) {
	return req(url, "GET", data, header, options, noLoading)
}
const post = function(url, data = {}, header = {}, options = {}, noLoading) {
	return req(url, "POST", data, header, options, noLoading)
}
const formpost = function(url, data = {}, header = {}, options = {}, noLoading) {
	let _head = {
		"content-type": "application/x-www-form-urlencoded"
	}
	Object.assign(header, _head)
	return req(url, "POST", data, header, options, noLoading)
}
request.get = get
request.post = post
request.formpost = formpost
request.req = req

export default request