/**
 * Created by rockyl on 2019-09-19.
 */

import {API_HOST} from "../config";
import {stringify} from "querystringify";

class ApiError extends Error {
	constructor(name, code, message, details) {
		super();

		if (name) {
			this.name = name;
		}
		if (code) {
			this.code = code;
		}
		if (message) {
			this.message = message;
		}
		if (details) {
			this.details = details;
		}
	}
}

export async function fetchApi(uri, {host = '', params, method = 'get', auth = true, credentials = 'include', judgeSuccess = true, contentType = 'json', dataField = 'data', errMessage} = {}) {
	let url = host + (uri.startsWith('http') || uri.startsWith('//') ? uri : API_HOST + uri);

	const options = {
		method,
		headers: {},
		credentials,
	};
	if (auth) {
		//options.headers.authorization = 'Bearer ' + window['zeroing_token'];
	}
	if (params) {
		if (method.toLowerCase() === 'post') {
			switch (contentType) {
				case 'form-data':
					let formData = new FormData();
					for (let key in params) {
						let value = params[key];
						if (value instanceof File) {
							formData.append(key, value, value.name);
						} else {
							formData.append(key, value);
						}
					}
					options.body = formData;
					break;
				case 'form':
					options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
					options.body = stringify(params);
					break;
				case 'json':
					options.headers['Content-Type'] = 'application/json';
					options.body = JSON.stringify(params);
					break;
			}
		} else {
			url += (url.indexOf('?') < 0 ? '?' : '');
			url += (url.endsWith('?') ? '' : '&') + stringify(params);
		}
	}

	const response = await fetch(url, options);
	const respText = await response.text();

	if (response.status === 310) {  //客户端重定向,用于跨域重定向
		location.href = respText;
	}

	try {
		let jsonObj = JSON.parse(respText);
		if (judgeSuccess) {
			if (jsonObj.success) {
				return jsonObj.data;
			}
		} else {
			return jsonObj;
		}

		return Promise.reject(new ApiError('call api failed', jsonObj.code, errMessage, jsonObj.details));
	}catch (e) {
		return Promise.reject(e);
	}
}
