class Request {
	config = {
		baseUrl: '', // 请求的根域名
		// 默认的请求头
		header: {
			'content-type': 'application/json;charset=UTF-8'
		},
		method: 'POST',
		// 设置为json，返回后uni.request会对数据进行一次JSON.parse
		dataType: 'json',
		// 此参数无需处理，因为5+和支付宝小程序不支持，默认为text即可
		responseType: 'text',
		showLoading: true, // 是否显示请求中的loading
		loadingText: '请求中...',
		loadingTime: 800, // 在此时间内，请求还没回来的话，就显示加载中动画，单位ms
		timer: null, // 定时器
		originalData: false, // 是否在拦截器中返回服务端的原始数据，见文档说明
		loadingMask: true, // 展示loading的时候，是否给一个透明的梦层，防止触摸穿透
	}

	// 判断是否http|https开头的URL
	static isHttp(url) {
		return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
	}

	// 拦截器
	interceptor = {
		// 请求前的拦截
		request: null,
		// 请求后的拦截
		response: null
	}

	// 设置全局默认配置
	setConfig(customConfig) {
		this.config = Object.assign(this.config, customConfig);
	}

	// 主要请求部分
	async request(options = {}) {
		options.dataType = options.dataType || this.config.dataType;
		options.responseType = options.responseType || this.config.responseType;
		options.url = options.url || '';
		options.params = options.params || {};
		options.header = options.header || this.config.header;
		options.method = options.method || this.config.method;
		
		// 检查请求拦截
		if (this.interceptor.request && typeof this.interceptor.request === 'function') {
			let tmpConfig = {};
			let interceptorReuest = this.interceptor.request(options);
			if (interceptorReuest === false) {
				return false;
			}
			this.options = interceptorReuest;
		}

		return new Promise((resolve, reject) => {
			options.complete = (response) => {
				// 请求返回后，隐藏loading(如果请求返回快的话，可能会没有loading)
				uni.hideLoading();
				// 清除定时器，如果请求回来了，就无需loading
				clearTimeout(this.config.timer);
				// 判断用户对拦截返回数据的要求，如果originalData为true，返回所有的数据(response)到拦截器，否则只返回response.data
				if(this.config.originalData) {
					// 判断是否存在拦截器
					if (this.interceptor.response && typeof this.interceptor.response === 'function') {
						let resInterceptors = this.interceptor.response(response);
						// 如果拦截器不返回false，就将拦截器返回的内容给this.$u.post的then回调
						if (resInterceptors !== false) {
							resolve(resInterceptors);
						} else {
							// 如果拦截器返回false，意味着拦截器定义者认为返回有问题，直接接入catch回调
							reject(response);
						}
					} else {
						// 如果要求返回原始数据，就算没有拦截器，也返回最原始的数据
						resolve(response);
					}
				} else {
					if (response.statusCode == 200) {
						if (this.interceptor.response && typeof this.interceptor.response === 'function') {
							let resInterceptors = this.interceptor.response(response.data);
							if (resInterceptors !== false) {
								resolve(resInterceptors);
							} else {
								reject(response);
							}
						} else {
							// 如果不是返回原始数据(originalData=false)，且没有拦截器的情况下，返回纯数据给then回调
							resolve(response.data);
						}
					} else {
						// 不返回原始数据的情况下，服务器状态码不为200，modal弹框提示
						if(response.errMsg) {
							uni.showModal({
								title: response.errMsg
							});
						}
						reject(response)
					}
				}
			}

			// 判断用户传递的URL是否/开头,如果不是,加上/
			options.url = Request.isHttp(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ?
				options.url : '/' + options.url));
			
			// 是否显示loading
			if(this.config.showLoading) {
				this.config.timer = setTimeout(() => {
					uni.showLoading({
						title: this.config.loadingText,
						mask: this.config.loadingMask
					})
				}, this.config.loadingTime);
			}
			uni.request(options)
		})
	}

	constructor() {
		// get请求
		this.get = (url, data, options = {}) => {
			return this.request({
				method: 'GET',
				url,
				...options,
				data
			})
		}

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

export default new Request
