import InterceptorManager from '@/utils/Http/InterceptorManager'
import dispatchRequest from '@/utils/Http/dispatchRequest';
import _ from '@/assets/scripts/lodash';

function Http(instanceConfig) {
	this.defaults = instanceConfig;
	this.interceptors = {
		request: new InterceptorManager(),
		response: new InterceptorManager()
	};
}

Http.prototype.request = function (config) {
	if (typeof config === 'string') {
		config = arguments[1] || {};
		config.url = arguments[0];
	} else {
		config = config || {};
	}
	
	config = Object.assign(this.defaults, config);
	config.method = config.method ? config.method.toUpperCase() : 'GET';
	
	let promise = Promise.resolve(config);
	const chain = [dispatchRequest, undefined];
	
	this.interceptors.request.forEach(interceptor => {
		chain.unshift(interceptor.resolve, interceptor.reject);
	});
	
	this.interceptors.response.forEach(interceptor => {
		chain.push(interceptor.resolve, interceptor.reject);
	});
	
	while(chain.length) {
		promise = promise.then(chain.shift(), chain.shift());
	}
	
	return promise;
}

_.forEach(['get', 'delete'], (method) => {
	Http.prototype[method] = function (url, config) {
		const params = config && config.params;
		if (params) {
			config.data = params;
		}
		return this.request(Object.assign(config || {}, {
			method: method.toUpperCase(),
			url,
			dataType: 'json'
		}));
	}
});

_.forEach(['post', 'put'], (method) => {
	Http.prototype[method] = function (url, data, config) {
		return this.request(Object.assign(config || {}, {
			method: method.toUpperCase(),
			url,
			data,
			dataType: 'json'
		}));
	}
});

export default Http;