/**
 * HTTP的封装， 基于uni.request
 * 包括： 通用响应结果的处理 和 业务的增删改查函数
 * 
 * @author terrfly
 * @site https://www.jeequan.com
 * @date 2021/12/16 18:35
 */
// 设置env配置文件
import envConfig from '@/env/config.js'
// 导入全局属性
import appConfig from '@/config/appConfig.js'
import storageManage from '@/commons/utils/storageManage.js'
import infoBox from "@/commons/utils/infoBox.js"
import go from '@/commons/utils/go.js';
import { reject } from 'lodash';
let baseUrl = appConfig.returnBaseUrl({apiType:'java'});
const loadingShowTime = 200

function getHeader(){
	const headerObject={}
	headerObject["token"] = storageManage.token()
	headerObject["shopId"] = uni.getStorageSync("shopInfo").id
	headerObject["platformType"] = 'APP'
	
	return headerObject
}

// 通用处理逻辑 
function commonsProcess(showLoading, httpReqCallback) {

	// 判断是否请求完成（用作 是否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 (statusCode == 500) {
			isShowErrorToast = true
			return Promise.reject(bodyData) // 跳转到catch函数
		}
		if (statusCode == 501) {
			// storageManage.token(null, true)
			// 提示信息
			isShowErrorToast = true
			// infoBox.showErrorToast('请登录').then(() => {
			// 	go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
			// })
			return Promise.reject(bodyData) // 跳转到catch函数
		}
		// http响应码不正确
		if (statusCode != 200 && statusCode != 204 && statusCode != 201) {
			isShowErrorToast = true
			bodyData.msg=bodyData.msg=='Bad credentials'?'用户名或密码错误':bodyData.msg
			infoBox.showToast(bodyData.msg || '服务器异常')
			return Promise.reject(bodyData) // 跳转到catch函数
		}

		// // 业务响应异常
		if (bodyData.hasOwnProperty('code') && bodyData.code != 200) {
			isShowErrorToast = true
			infoBox.showToast(bodyData.msg)
			// if (bodyData.code == 5005) { // 密码已过期， 直接跳转到更改密码页面
			// 	uni.reLaunch({
			// 		url: '/pageUser/setting/updatePwd'
			// 	})
			// }
			// if(bodyData.code == 500){ // 密码已过期， 直接跳转到更改密码页面
			// 	uni.redirectTo({url: '/pages/login/index'})
			// }
			return Promise.reject(bodyData) // 跳转到catch函数
		}

		// 构造请求成功的响应数据 
		return Promise.resolve(bodyData.data)

	}).catch(res => {
		console.log(res)
		if(res.code==501){
			storageManage.token(null, true)
			infoBox.showToast('登录过期,请重新登录').then(() => {
				uni.redirectTo({url: '/pages/login/index'})
				reject()
			})
		}
		// if(res.status==400){
		// 	storageManage.token(null, true)
		// 	infoBox.showErrorToast('').then(() => {
		// 		go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH)
		// 	})
		// }
		if(res.code==500){
			infoBox.showToast(res.msg||'服务器异常').then(() => {})
		}
		// if(res&&res.msg){
		// 	infoBox.showErrorToast(res.msg)
		// }
		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 = {}) {
	// headerObject[appConfig.tokenKey] = storageManage.token()
	return commonsProcess(showLoading, () => {
		return uni.request(
			Object.assign({
				url: baseUrl + uri,
				data: data,
				method: method,
				header: getHeader()
			}, extParams)
		)
	})
}


// 默认 显示loading(控制 xxs 内 不提示loading )
function request(args) {
	const {
		url,
		data,
		params,
		method = "GET",
		showLoading = true,
		extParams = {}
	} = args
	let headerObject = {}
	// headerObject[appConfig.tokenKey] = storageManage.token()
	return commonsProcess(showLoading, () => {
		return uni.request(
			Object.assign({
				url: baseUrl + url,
				data: params||data,
				method: method,
							header: getHeader()
			}, extParams)
			
		)
	})
}



// 上传
function upload(uri, data, file, showLoading = true, extParams = {}) {
	// 放置token
	let headerObject = {}
	// headerObject[appConfig.tokenKey] = storageManage.token()

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

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