import { isArray, isNumber, isString, orderBy } from "lodash-es";
import { resolveComponent } from "vue";
import storage from "./storage";

// 首字母大写
export function firstUpperCase(value: string): string {
	return value.replace(/\b(\w)(\w*)/g, function ($0, $1, $2) {
		return $1.toUpperCase() + $2;
	});
}

// 获取方法名
export function getNames(value: any) {
	return Object.getOwnPropertyNames(value.constructor.prototype);
}

// 获取地址栏参数
export function getUrlParam(name: string): string | null {
	const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
	const r = window.location.search.substr(1).match(reg);
	if (r != null) return decodeURIComponent(r[2]);
	return null;
}

// 文件名
export function filename(path: string): string {
	return basename(path.substring(0, path.lastIndexOf(".")));
}

// 路径名称
export function basename(path: string): string {
	let index = path.lastIndexOf("/");
	index = index > -1 ? index : path.lastIndexOf("\\");
	if (index < 0) {
		return path;
	}
	return path.substring(index + 1);
}

// 文件扩展名
export function extname(path: string): string {
	return path.substring(path.lastIndexOf(".") + 1).split(/(\?|&)/)[0];
}

// 横杠转驼峰
export function toCamel(str: string): string {
	return str.replace(/([^-])(?:-+([^-]))/g, function ($0, $1, $2) {
		return $1 + $2.toUpperCase();
	});
}

// uuid
export function uuid(separator = "-"): string {
	const s: any[] = [];
	const hexDigits = "0123456789abcdef";
	for (let i = 0; i < 36; i++) {
		s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
	}
	s[14] = "4";
	s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
	s[8] = s[13] = s[18] = s[23] = separator;

	return s.join("");
}

// 浏览器信息
export function getBrowser() {
	const { clientHeight, clientWidth } = document.documentElement;

	// 浏览器信息
	const ua = navigator.userAgent.toLowerCase();

	// 浏览器类型
	let type = (ua.match(/firefox|chrome|safari|opera/g) || "other")[0];

	if ((ua.match(/msie|trident/g) || [])[0]) {
		type = "msie";
	}

	// 平台标签
	let tag = "";

	const isTocuh =
		"ontouchstart" in window || ua.indexOf("touch") !== -1 || ua.indexOf("mobile") !== -1;
	if (isTocuh) {
		if (ua.indexOf("ipad") !== -1) {
			tag = "pad";
		} else if (ua.indexOf("mobile") !== -1) {
			tag = "mobile";
		} else if (ua.indexOf("android") !== -1) {
			tag = "androidPad";
		} else {
			tag = "pc";
		}
	} else {
		tag = "pc";
	}

	// 浏览器内核
	let prefix = "";

	switch (type) {
		case "chrome":
		case "safari":
		case "mobile":
			prefix = "webkit";
			break;
		case "msie":
			prefix = "ms";
			break;
		case "firefox":
			prefix = "Moz";
			break;
		case "opera":
			prefix = "O";
			break;
		default:
			prefix = "webkit";
			break;
	}

	// 操作平台
	const plat = ua.indexOf("android") > 0 ? "android" : navigator.platform.toLowerCase();

	// 屏幕信息
	let screen = "full";

	if (clientWidth < 768) {
		screen = "xs";
	} else if (clientWidth < 992) {
		screen = "sm";
	} else if (clientWidth < 1200) {
		screen = "md";
	} else if (clientWidth < 1920) {
		screen = "xl";
	} else {
		screen = "full";
	}

	// 是否 ios
	const isIOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

	// 是否 PC 端
	const isPC = tag === "pc";

	// 是否移动端
	const isMobile = isPC ? false : true;

	// 是否移动端 + 屏幕宽过小
	const isMini = screen === "xs" || isMobile;

	return {
		height: clientHeight,
		width: clientWidth,
		type,
		plat,
		tag,
		prefix,
		isMobile,
		isIOS,
		isPC,
		isMini,
		screen
	};
}

// 路径转数组
export function deepPaths(paths: string[], splitor?: string) {
	const list: any[] = [];

	paths.forEach((e) => {
		const arr: string[] = e.split(splitor || "/").filter(Boolean);

		let c = list;

		arr.forEach((a, i) => {
			let d = c.find((e) => e.label == a);

			if (!d) {
				d = {
					label: a,
					value: a,
					children: arr[i + 1] ? [] : null
				};

				c.push(d);
			}

			if (d.children) {
				c = d.children;
			}
		});
	});

	return list;
}

// 列表转树形
export function deepTree(list: any[], sort?: "desc" | "asc"): any[] {
	const newList: any[] = [];
	const map: any = {};

	orderBy(list, "orderNum", sort)
		.map((e) => {
			map[e.id] = e;
			return e;
		})
		.forEach((e) => {
			const parent = map[e.parentId];

			if (parent) {
				(parent.children || (parent.children = [])).push(e);
			} else {
				newList.push(e);
			}
		});

	return newList;
}

// 树形转列表
export function revDeepTree(list: any[]) {
	const arr: any[] = [];
	let id = 0;

	function deep(list: any[], parentId: number) {
		list.forEach((e) => {
			if (!e.id) {
				e.id = ++id;
			}

			if (!e.parentId) {
				e.parentId = parentId;
			}

			arr.push(e);

			if (e.children && isArray(e.children) && e.id) {
				deep(e.children, e.id);
			}
		});
	}

	deep(list || [], 0);

	return arr;
}

// 路径转对象
export function path2Obj(list: any[]) {
	const data: any = {};

	list.forEach(({ path, value }) => {
		if (path) {
			const arr: string[] = path.split("/");
			const parents = arr.slice(0, arr.length - 1);
			const name = basename(path).replace(".ts", "");

			let curr = data;

			parents.forEach((k) => {
				if (!curr[k]) {
					curr[k] = {};
				}

				curr = curr[k];
			});

			curr[name] = value;
		}
	});

	return data;
}

// 是否是组件
export function isComponent(name: string) {
	return !isString(resolveComponent(name));
}

// 是否Promise
export function isPromise(val: any) {
	return val && Object.prototype.toString.call(val) === "[object Promise]";
}

// 单位转换
export function parsePx(val: string | number) {
	return isNumber(val) ? `${val}px` : val;
}

// 延迟
export function sleep(duration: number) {
	return new Promise((resolve) => {
		setTimeout(() => {
			resolve(true);
		}, duration);
	});
}

export { storage };
export * from "./loading";
