import Vue from "vue";
import axios from "axios";
import {
	baseURL,
	contentType,
	debounce,
	invalidCode,
	noRoleCode,
	requestTimeout,
	successCode,
	tokenName,
	title,
} from "@/config/settings";
import store from "@/store";
import qs from "qs";
import router from "@/router";
import {
	isArray,
	isUpperCase
} from "@/utils/validate";
import {
	getEnToken
} from "@/utils/accessToken";
let loadingInstance;

/**
 * @description 处理code异常
 * @param {*} code
 * @param {*} msg
 */
const handleCode = (code, msg) => {
	Vue.prototype.$baseColorfullLoading().close();
	switch (code) {
		case invalidCode:
			Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
			store.dispatch("user/resetAll").catch(() => {});
			break;
		case noRoleCode:
			router.push({
				path: "/401"
			}).catch(() => {});
			break;
		default:
			Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
			break;
	}
};

/**

 * @description axios初始化
 */
const instance = axios.create({
	baseURL,
	timeout: requestTimeout,
	// responseType: "arraybuffer",
	headers: {
		"Content-Type": contentType,
	},
});

/**

 * @description axios请求拦截器
 */
instance.interceptors.request.use(
	(config) => {
		if (store.getters["user/accessToken"])
			config.headers[tokenName] = store.getters["user/accessToken"];
		if (getEnToken()) {
			config.headers.Token = getEnToken();
		}
		if (store.getters["MUser/systemType"] === 2) {
			config.headers["SHOP-TOKEN"] =
				store.getters["MUser/storeData"].token || "";
		}
		if (
			config.data &&
			config.headers["Content-Type"] ===
			"application/x-www-form-urlencoded;charset=UTF-8"
		)
		config.data = qs.stringify(config.data);
		// // console.log(isUpperCase(config.method),config.method,config.data,'qq')
		// if (isUpperCase(config.method) ? config.method === "GET" : config.method === "get") {
		// 	config.params = config.data
		// }
		if (debounce.some((item) => config.url.includes(item)))
			loadingInstance = Vue.prototype.$baseLoading();
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);

/**

 * @description axios响应拦截器
 */
instance.interceptors.response.use(
	(response) => {
		// console.log(response);
		if (loadingInstance) loadingInstance.close();
		const {
			data,
			config
		} = response;
		if (data.errorcode >= 0) {
			const code = data.errorcode;
			const msg = data.data;
			// 操作正常Code数组
			const codeVerificationArray = isArray(successCode) ?
				[...successCode] :
				[...[successCode]];
			// 是否操作正常
			if (codeVerificationArray.includes(code)) {
				return data;
			} else {
				handleCode(code, msg);
				return Promise.reject(
					title +
					"请求异常拦截:" +
					JSON.stringify({
						url: config.url,
						code,
						msg
					}) || "Error"
				);
			}
		} else if (data.size) {
			/*
			 * 导出
			 * */
			// 时间戳
			let fileName = Date.parse(new Date()) + ".csv";
			// 创建a标签
			let link = document.createElement("a");
			// 打开url
			// link.href = window.URL.createObjectURL(data);
			link.href = window.URL.createObjectURL(
				new Blob([data], {
					type: "application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
				})
			);
			// 下载
			link.download = fileName;
			link.click();
			// 释放内存
			window.URL.revokeObjectURL(link.href);
			return data;
		}
	},
	(error) => {
		if (loadingInstance) loadingInstance.close();
		const {
			response,
			message
		} = error;
		if (error.response && error.response.data) {
			const {
				status,
				data
			} = response;
			handleCode(status, data.msg || message);
			return Promise.reject(error);
		} else {
			let {
				message
			} = error;
			if (message === "Network Error") {
				message = "后端接口连接异常";
			}
			if (message.includes("timeout")) {
				message = "-1";
				// message = "后端接口请求超时";
			}
			if (message.includes("Request failed with status code")) {
				const code = message.substr(message.length - 3);
				message = "后端接口" + code + "异常";
			}
			if (message !== "-1") {
				Vue.prototype.$baseMessage(message || `后端接口未知异常`, "error");
			}
			return Promise.reject(error);
		}
	}
);

export default instance;
