/* eslint-disable no-const-assign */
import { defaultErrMsg } from "./constants";

export function promisify(func) {
	return function wrapPromisify(args) {
		return new Promise((resolve) => {
			func({
				...args,
				success(res) {
					resolve([null, res]);
				},
				fail(err) {
					resolve([err, null]);
				},
			});
		});
	};
}

export function promisifyCallback(func) {
	return function wrapPromisifyCallback(args) {
		return new Promise((resolve) => {
			func({
				...args,
				callback(res) {
					resolve(res);
				},
			});
		});
	};
}

// 缓存处理
const clearStorage = promisify(my.clearStorage);
const removeStorage = promisify(my.removeStorage);
const getStorage = promisify(my.getStorage);
const setStorage = promisify(my.setStorage);
export const storageAPI = {
	clearStorage,
	getStorage,
	setStorage,
	removeStorage,
};

const getAuthCode = promisify(my.getAuthCode);

export async function getSilentAuthCode() {
	const res = await getAuthCode({
		scopes: "auth_base",
	});
	return res;
}

export async function getAuthUser(scopesList) {
	const res = await getAuthCode({
		scopes: scopesList || "auth_user",
	});
	return res;
}

export async function getOpenUserInfo() {
	return new Promise((resove) => {
		my.getOpenUserInfo({
			success: (res) => {
				const { response } = JSON.parse(res.response);
				if (response.code === "10000") {
					resove([null, response]);
				} else {
					resove([response, null]);
				}
			},
			fail: (err) => {
				resove([err, null]);
			},
		});
	});
}

// 获取appID
export function getAppId() {
	const res = my.getAppIdSync();
	const { appId = "" } = res;
	return appId;
}

export async function getPhoneNumber() {
	// 小程序模板所属的三方应用获取手机号需要传入isvAppId
	const app = getApp();
	let params = {};
	if (app.globalData.isvAppId) {
		params = { protocols: { isvAppId: app.globalData.isvAppId } };
	}
	const [err, res] = await promisify(my.getPhoneNumber)(params);
	if (err) return [err, null];
	const encryptedData = res.response;
	return [null, encryptedData];
}

export async function getIDNumber() {
	const [err, res] = await promisify(my.getIDNumber)();
	if (err) return [err, null];
	const encryptedData = res.response;
	return [null, encryptedData];
}

export const getLoaction = promisify(my.getLocation);

export const STORAGE_MINIPROGRAM_ALIPAY_UID_KEY =
	"STORAGE_MINIPROGRAM_ALIPAY_UID";

let alipay_logger_uid = "";

export function autoGenUid() {
	const o = Date.now().toString(36).split("");
	let n = 20;
	const r = new Array(n);
	let e;
	let t;
	// eslint-disable-next-line no-plusplus
	while (n-- > 0) {
		// eslint-disable-next-line no-bitwise
		e = (t = (36 * Math.random()) | 0).toString(36);
		r[n] = t % 3 ? e : e.toUpperCase();
	}
	for (let i = 0; i < 8; i++) {
		r.splice(3 * i + 2, 0, o[i]);
	}
	return r.join("");
}

export function autoGetUid() {
	return alipay_logger_uid;
}

export function autoSetUid() {
	if (typeof my !== "undefined" && my && typeof my.getStorage === "function") {
		try {
			my.getStorage({
				key: STORAGE_MINIPROGRAM_ALIPAY_UID_KEY,
				success(e) {
					if (e && e.data && typeof e.data === "string") {
						alipay_logger_uid = e.data;
					} else if (typeof my.setStorage === "function") {
						const uid = autoGenUid();
						my.setStorage({
							key: STORAGE_MINIPROGRAM_ALIPAY_UID_KEY,
							data: uid,
							success() {
								alipay_logger_uid = uid;
								console.log(
									"[cloudMonitor] info: setStorage uid success, ",
									uid
								);
							},
							fail(t) {
								console.log("[cloudMonitor] error in setStorage", t);
							},
						});
					}
				},
				fail(t) {
					console.log("[cloudMonitor] error in getStorage", t);
				},
			});
		} catch (e) {
			console.log("[cloudMonitor] error in autoSetUid", e);
		}
	}
}

// systemInfo可以保存到本地
export const getSystemInfo = async function () {
	try {
		const [sysErr, sysInfo] = await promisify(my.getSystemInfo)();
		const [netErr, netInfo] = await promisify(my.getNetworkType)();
		const [evnErr, envInfo] = await promisify(my.getRunScene)();
		let result = {
			sdkVersion: my.SDKVersion,
			uid: autoGetUid(),
			timestamp: Date.now(),
		};

		if (sysErr == null) {
			result = { ...result, ...sysInfo };
		}

		if (netErr == null) {
			result = { ...result, ...netInfo };
		}

		if (evnErr == null) {
			result = { ...result, ...envInfo };
		}

		return result;
	} catch (e) {
		console.log(e);
	}
};

export async function getTitleBarHeight() {
	const [, res] = await promisify(my.getSystemInfo)();
	const titleBarHeight =
		(res.statusBarHeight || 24) + (res.titleBarHeight || 40);
	return titleBarHeight;
}

export const navigateToMiniProgram = promisify(my.navigateToMiniProgram);

export const navigateToAlipayPage = async (config) =>
	new Promise((resolve, reject) => {
		try {
			my.ap.navigateToAlipayPage({
				...config,
				success: (res) => {
					resolve(res);
				},
				fail: (res) => {
					console.log("navigateToAlipayPage--fail====", res, config);
					reject(res);
				},
			});
		} catch (e) {
			reject(e);
		}
	});

export function alert(title = defaultErrMsg, content = "") {
	my.alert({
		title,
		content,
	});
}

export const toast = function (content = defaultErrMsg) {
	my.showToast({
		content,
	});
};

export const startAPVerify = function (certifyId, certifyUrl) {
	return new Promise((resolve) => {
		my.startAPVerify({
			url: certifyUrl,
			certifyId,
			success(res) {
				if (res.resultStatus === "9000") {
					resolve([null, res]);
				} else {
					const err = new Error(
						`实人认证失败，不能失败的状态码:${res.resultStatus}`
					);
					resolve([err, null]);
				}
			},
			fail(err) {
				resolve([err, null]);
			},
		});
	});
};

export const getServerTime = promisify(my.getServerTime);

export const checkAppVersion = function () {
	const updateManager = my.getUpdateManager();
	// 请求完新版本信息的回调
	updateManager.onCheckForUpdate((res) => {
		console.log(res.hasUpdate);
	});
	// 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
	updateManager.onUpdateReady(() => {
		my.confirm({
			title: "更新提示",
			content: "新版本已经准备好，是否重启应用？",
			success(res) {
				if (res.confirm) {
					updateManager.applyUpdate();
				}
			},
		});
	});
	// 新版本下载失败
	updateManager.onUpdateFailed(() => {
		my.alert({ title: "更新失败" });
	});
};

// ali埋点
export function aliTracertTa(params) {
	const Tracert =
		my.ap.createTracert &&
		my.ap.createTracert({
			spmAPos: "a1", // spma位，必填
			spmBPos: "b1", // spmb位，必填
			bizType: "alipaysaas", // 业务类型
			logLevel: 2, // 默认是2
			chInfo: "", // 渠道
			mdata: {
				// 通用的数据，可不传，传了所有的埋点均会带该额外参数
			},
			debug: false, // 默认是false，传true 则会在发起埋点请求的时候，在控制台输出日志
			...params,
		});
	return Tracert || { click: () => null, expo: () => null, logPv: () => null };
}
