// 导入全局属性
import {
	sm4DecryptByResData
} from "@/utils/encryptUtil.js";
import infoBox from "@/utils/infoBox.js";
import {
	reject
} from "lodash";
import config from "@/commons/config.js";

// 测试服
let baseUrl = config.baseApiUrl + "app";
const loadingShowTime = 200;

function getHeader(data) {
	const header = data ? data.header : {}
	const headerObject = {
		...header
	};
	headerObject["token"] = uni.getStorageSync("token");
	return headerObject;
}

// 通用处理逻辑
function commonsProcess(showLoading, httpReqCallback, isreturm) {
	// 判断是否请求完成（用作 是否loading ）
	// 包括： 'ing', 'ingLoading', 'finish'
	let reqState = "ing";
	// 是否已经提示的错误信息
	let isShowErrorToast = false;
	// 请求完成， 需要处理的动作
	let reqFinishFunc = () => {
		if (reqState == "ingLoading") {
			// 关闭loading弹层
			infoBox.hideLoading();
		}
		reqState = "finish"; // 请求完毕
	};
	// 明确显示loading
	if (showLoading) {
		// xx ms内响应完成，不提示loading
		setTimeout(() => {
			if (reqState == "ing") {
				reqState = "ingLoading";
				infoBox.showLoading();
			}
		}, loadingShowTime);
	}

	return httpReqCallback()
		.then((httpData) => {

			reqFinishFunc(); // 请求完毕的动作
			// 从http响应数据中解构响应数据 [ 响应码、 bodyData ]
			let {
				statusCode,
				data
			} = httpData;
			// 避免混淆重新命名
			let bodyData = data;
			if (isreturm) {
				return Promise.resolve(bodyData);
			}

			if (statusCode == 500) {
				isShowErrorToast = true;
				return Promise.reject(bodyData); // 跳转到catch函数
			}

			if (statusCode == 401) {
				// 提示信息
				isShowErrorToast = true;
				return Promise.reject(bodyData); // 跳转到catch函数
			}
			// http响应码不正确
			if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
				isShowErrorToast = true;
				infoBox.showToast(data.message || "服务器异常");
				return Promise.reject(bodyData); // 跳转到catch函数
			}
			if (bodyData.code == 401) {
				// 提示信息
				isShowErrorToast = true;
				return Promise.reject(bodyData); // 跳转到catch函数
			}
			if (bodyData.code == 701) {
				uni.clearStorageSync()
				uni.reLaunch({
					url: '/pages/login/login'
				})
				return Promise.reject(bodyData); // 跳转到catch函数
			}
			if (bodyData.code == 702) {
				return Promise.reject(bodyData); // 跳转到catch函数
			}
			if (bodyData.code == 500) {
				// 提示信息
				isShowErrorToast = true;
				return Promise.reject(bodyData); // 跳转到catch函数
			}


			let result = null;
			if (bodyData.hasOwnProperty('data')) {
				result = bodyData.data
			} else if (bodyData.hasOwnProperty('page')) {
				result = bodyData.page
			} else {
				result = bodyData
			}

			//未绑定微信
			if (bodyData.code == 407) {
				return Promise.resolve(result);
			}



			if (bodyData.code != 0) {
				infoBox.showToast(data.message);
				return;
			}

			// 加密数据
			if (!bodyData.data && bodyData.encryptData) {
				return Promise.resolve({
					bizData: sm4DecryptByResData(bodyData.encryptData),
					code: bodyData.code,
				});
			}


			// 构造请求成功的响应数据
			return Promise.resolve(result);
		})
		.catch((res) => {

			if (res.status == 404) {
				infoBox.showToast("接口404").then(() => {});
				reject();
				return;
			}

			if (res.code == 401) {
				uni.redirectTo({
					url: "/pages/login/login",
				});
				reject();
			}
			if (res.code != 0 && res.code != 401) {
				infoBox.showToast(res.msg).then(() => {});
				reject();
			}
			if (res.code == 500) {
				infoBox.showToast(res.msg || "服务器异常").then(() => {});
				reject();
			}
			reqFinishFunc(); // 请求完毕的动作

			// 如果没有提示错误， 那么此处提示 异常。
			if (!isShowErrorToast) {
				infoBox.showToast(`请求网络异常`);
			}

			return Promise.reject(res);
		})
		.finally(() => {
			// finally 是 then结束后再执行, 此处不适用。  需要在请求完成后立马调用： reqFinishFunc()
		});
}

// 默认 显示loading(控制 xxs 内 不提示loading )
function req(uri, data, method = "GET", showLoading = true, extParams = {}) {
	return commonsProcess(showLoading, () => {
		return uni.request(
			Object.assign({
					url: baseUrl + uri,
					data: data,
					method: method,
					header: getHeader(data),
				},
				extParams
			)
		);
	});
}

// 默认 显示loading(控制 xxs 内 不提示loading )
function request(args) {
	let {
		url,
		data,
		params,
		method = "GET",
		showLoading = true,
		extParams = {},
		isreturm = false
	} = args
	if (params) {
		let result = ''
		Object.keys(params).forEach((key) => {
			if (!Object.is(params[key], undefined) && !Object.is(params[key], null) && !Object.is(JSON
					.stringify(params[key]), '{}')) {
				result += encodeURIComponent(key) + '=' + encodeURIComponent(params[key]) + "&"
			}
		})
		url = url + '?' + (result.slice(0, result.length - 1))
		params = null
	}
	let headerObject = {}
	return commonsProcess(showLoading, () => {
		return uni.request(
			Object.assign({
				url: slash(baseUrl, url),
				data: params || data,
				method: method,
				header: getHeader(data)
			}, extParams)

		)
	}, isreturm)
}
// 处理/
function slash(baseUrl, url) {
	let u = "";
	if (baseUrl[baseUrl.length - 1] == "/") {
		u += baseUrl;
	} else {
		u = u + baseUrl + "/";
	}
	if (url[0] == "/") {
		u = u + url.slice(1);
	} else {
		u = u + url;
	}
	return u;
}

// 上传
function upload(uri, data, file, showLoading = true, extParams = {}) {
	// 放置token
	let headerObject = {};
	return commonsProcess(showLoading, () => {
		return uni
			.uploadFile(
				Object.assign({
						url: baseUrl + uri,
						formData: data,
						name: "file",
						filePath: file.path || file.url,
						header: getHeader(data),
					},
					extParams
				)
			)
			.then((httpData) => {
				// uni.upload 返回bodyData 的是 string类型。 需要解析。
				httpData.data = JSON.parse(httpData.data);
				return Promise.resolve(httpData);
			})
			.catch((err) => {
				uni.hideLoading();
				infoBox.showToast(`上传失败`);
			});
	});
}

export default {
	req: req,
	request,
	upload: upload,
};