const baseurl = require("../env.js");
export default class Request {
	constructor() {
		// 默认配置
		this.config = {
			baseUrl: baseurl,
			header: {
				'content-type': 'application/json',
			},
			url: '',
			data: {},
			params: {},
			method: 'GET',
			dataType: 'json',
			responseType: 'text',
			custom: {},
			sslVerify: false
		}

		/* 拦截器 */
		this.interceptor = {
			request: cb => {
				if (cb) {
					this.requestBefore = cb
				} else {
					this.requestBefore = request => request
				}
			},
			response: (cb) => {
				if (cb) {
					this.requestAfter = cb
				} else {
					this.requestAfter = response => response
				}
			}
		}
	}

	/* 判断url是否完整 */
	static isUrl(url) {
		return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
	}

	static addQueryString(params) {
		let paramsData = ''
		Object.keys(params).forEach(key => {
			paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
		})
		return paramsData.substring(0, paramsData.length - 1)
	}

	/* 请求前 */
	static requestBefore(config) {
		return config
	}

	/* 请求后 */
	static requestAfter(response) {
		return response
	}

	/*设置全局配置*/
	setConfig(func) {
		return func(this.config)
	}

	/**
	 * @Function
	 * @param {Object} options - 请求配置项
	 * @prop {String} options.url - 请求路径
	 * @prop {Object} options.data - 请求参数
	 * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
	 * @prop {Object} [options.dataType = config.dataType] - 如果设为 json，会尝试对返回的数据做一次 JSON.parse
	 * @prop {Object} [options.header = config.header] - 请求header
	 * @prop {Object} [options.method = config.method] - 请求方法
	 * @returns {Promise<unknown>}
	 */
	async request(options = {}) {
		options = {
			...options,
			...this.config,
			...this.requestBefore(options)
		}
		return new Promise((resolve, reject) => {
			let mergeUrl = Request.isUrl(options.url) ? options.url : (options.baseUrl + options.url)
			if (JSON.stringify(options.params) !== '{}') {
				let query = Request.addQueryString(options.params);
				mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${query}` : `&${query}`
			}
			options.url = mergeUrl
			options.success = res => {
				resolve(this.requestAfter(res.data))
			}
			options.fail = err => {
				reject(this.requestAfter(err))
			}
			uni.request(options)
		})
	}

	get(url, options = {}) {
		return this.request({
			url,
			method: 'GET',
			...options
		})
	}

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

}