/**
 * Request:请求封装
 * @property {Object} config = 私有属性，默认值
 * @property {Function} isUrl = 私有方法，url是否完整
 * @property {Function} requestBefore = 私有方法，请求前
 * @property {Function} requestAfter = 私有方法，请求后
 */
import {} from '@/env'
import platform from '@/rokeTools/platform/index';
import _ from 'lodash';
export default class Request {
	constructor() {
		// 默认配置
		this.configDefault = {
			baseUrl: '',
			header: {
				'Content-Type': 'application/json',
				'platform': platform.get()
			},
			data: {},
			params: {},
			method: 'GET',
			dataType: 'json',
			// #ifndef MP-ALIPAY || APP-PLUS
			responseType: 'text',
			// #endif
			custom: {},
			// #ifdef APP-PLUS
			sslVerify: false
			// #endif
		}
		this.config = JSON.parse(JSON.stringify(this.configDefault));

		/* 拦截器 */
		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) {
		this.config = JSON.parse(JSON.stringify(this.configDefault));
		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 = {}) {
		let opt = this.requestBefore(options)
		options = _.merge(this.config, opt);
		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;
			// console.log(JSON.stringify(options));
			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
		})
	}

}