import axios from 'axios';
import { ElNotification, ElMessageBox, ElMessage } from 'element-plus';
import sysConfig from "@/config";
import tool from '@/utils/tool';
import router from '@/router';
import {closeSock} from "@/utils/websocket"

axios.defaults.baseURL = ''

axios.defaults.timeout = sysConfig.TIMEOUT

// HTTP request 拦截器
axios.interceptors.request.use(
	(config) => {
		let token = tool.cookie.get("TOKEN");
		if(token){
			config.headers[sysConfig.TOKEN_NAME] = sysConfig.TOKEN_PREFIX + token
		}
		if(!sysConfig.REQUEST_CACHE && config.method == 'get'){
			config.params = config.params || {};
			config.params['_'] = new Date().getTime();
		}
		Object.assign(config.headers, sysConfig.HEADERS)
		return config;
	},
	(error) => {
		return Promise.reject(error);
	}
);

//FIX 多个API同时401时疯狂弹窗BUG
let MessageBox_401_show = false

// HTTP response 拦截器
axios.interceptors.response.use(
	(response) => {
		const token = response.headers.authorization;
		if (token) {
			let reToken = token.replace(/Bearer /g, "");
			tool.cookie.set("TOKEN", reToken);
		}
		const api_code = response.data.code;
		if (api_code === 401) {
			if (!MessageBox_401_show) {
				MessageBox_401_show = true;
				ElMessageBox.confirm(response.data.message,"无权限访问",{
					type: "error",
					closeOnClickModal: false,
					center: true,
					confirmButtonText: "重新登录",
					beforeClose: (action, instance, done) => {
						MessageBox_401_show = false;
						done();
					},
				}).then(() => {
					try {
						closeSock(true);
					}catch(err) {
						console.log(err)
					}
					tool.data.clear();
					tool.cookie.remove("TOKEN");
					router.replace({path: "/login"});
				})
				.catch(() => {});
			}
		} else if (api_code === 404) {
			ElNotification.error({
				title: "请求错误",
				message: "Status:404，正在请求不存在的接口！",
			});
		} else if (api_code === 500) {
			ElNotification.error({
				title: "请求错误",
				message: response.data.msg || "Status:500，服务器发生错误！",
			});
		} else if (api_code === 0 || api_code !== 200) {
			const contentType = response.headers.get('Content-Type');
			if(contentType.includes('application/json')){
				ElMessage.warning(response.data.message);
			}
		}

		return response;

	},
	(error) => {
		ElNotification.error({
			title: '请求错误',
			message: "请求服务器无响应！"
		});
		return Promise.reject(error.response);
	}
);

const http = {

	/** get 请求
	 * @param  {string} url 接口地址
	 * @param  {object} params 请求参数
	 * @param  {object} config 参数
	 */
	get: function (url, params = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'get',
				url: url,
				params: params,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** post 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	post: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'post',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** oss 请求
	 * @param  {string} url
	 * @param  {{}} data
	 * @param  {{}} config
	 */
	oss: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: "post",
				url: url,
				data: data,
				...config,
			})
				.then((response) => {
					resolve(response.data);
				})
				.catch((error) => {
					reject(error);
				});
		});
	},

	/** put 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	put: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'put',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** patch 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	patch: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'patch',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** delete 请求
	 * @param  {string} url 接口地址
	 * @param  {object} data 请求参数
	 * @param  {object} config 参数
	 */
	delete: function (url, data = {}, config = {}) {
		return new Promise((resolve, reject) => {
			axios({
				method: 'delete',
				url: url,
				data: data,
				...config
			}).then((response) => {
				resolve(response.data);
			}).catch((error) => {
				reject(error);
			})
		})
	},

	/** jsonp 请求
	 * @param  {string} url 接口地址
	 * @param  {string} name JSONP回调函数名称
	 */
	jsonp: function (url, name = 'jsonp') {
		return new Promise((resolve) => {
			const script = document.createElement('script');
			const _id = `jsonp${Math.ceil(Math.random() * 1000000)}`;
			script.id = _id
			script.type = 'text/javascript'
			script.src = url
			window[name] = (response) => {
				resolve(response)
				document.getElementsByTagName('head')[0].removeChild(script)
				try {
					delete window[name];
				} catch (e) {
					window[name] = undefined;
				}
			}
			document.getElementsByTagName('head')[0].appendChild(script)
		})
	}
};

export default http;
