import { BigNumber } from "bignumber.js";
/**
 * Check if an element has a class
 * @param {HTMLElement} ele
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele: HTMLElement, cls: string) {
	return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}

/**
 * Add class to element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function addClass(ele: HTMLElement, cls: string) {
	if (!hasClass(ele, cls)) ele.className += " " + cls;
}

/**
 * Remove class from element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function removeClass(ele: HTMLElement, cls: string) {
	if (hasClass(ele, cls)) {
		const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
		ele.className = ele.className.replace(reg, " ");
	}
}

/**
 * 判断是否是外部链接
 *
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path: string) {
	const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
	return isExternal;
}

/**
 * 格式化增长率，保留两位小数 ，并且去掉末尾的0  取绝对值
 *
 * @param growthRate
 * @returns
 */
export function formatGrowthRate(growthRate: number) {
	if (growthRate === 0) {
		return "-";
	}

	const formattedRate = Math.abs(growthRate * 100)
		.toFixed(2)
		.replace(/\.?0+$/, "");
	return formattedRate + "%";
}
/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time: string | number | Date | null, cFormat: string | undefined) {
	if (arguments.length === 0) {
		return null;
	}
	const format = cFormat || "{y}-{m}-{d} {h}:{i}:{s}";
	let date;
	if (typeof time === "undefined" || time === null || time === "null") {
		return "";
	} else if (typeof time === "object") {
		date = time;
	} else {
		if (typeof time === "string" && /^[0-9]+$/.test(time)) {
			time = parseInt(time);
		}
		if (typeof time === "number" && time.toString().length === 10) {
			time = time * 1000;
		}
		date = new Date(time);
	}
	const formatObj = {
		y: date.getFullYear(),
		m: date.getMonth() + 1,
		d: date.getDate(),
		h: date.getHours(),
		i: date.getMinutes(),
		s: date.getSeconds(),
		a: date.getDay()
	};
	const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key: keyof typeof formatObj): string => {
		let value = formatObj[key];
		// Note: getDay() returns 0 on Sunday
		if (key === "a") {
			return ["日", "一", "二", "三", "四", "五", "六"][value];
		}
		if (result.length > 0 && value < 10) {
			value = Number("0" + value.toString());
		}
		return value.toString() || "0";
	});
	return time_str;
}

// 下载文件
export function downloadFile(obj: BlobPart, name: string, suffix: string, useUnix = true) {
	const url = window.URL.createObjectURL(new Blob([obj]));
	const link = document.createElement("a");
	link.style.display = "none";
	link.href = url;
	// 期望行为：
	// - 当 useUnix 为 true 且传入 name 时：`${timestamp}-${name}`
	// - 当 useUnix 为 true 且 name 为空时：仅 `${timestamp}`（不带多余的 `-`）
	// - 当 useUnix 为 false：使用传入的 name（如为空则回退到时间戳）
	const safeName = (name || "").trim();
	const timeStamp = parseTime(new Date(), undefined);
	const fileBase = useUnix
		? (safeName ? `${timeStamp}-${safeName}` : timeStamp)
		: (safeName || timeStamp);
	const fileName = fileBase + "." + suffix;
	link.setAttribute("download", fileName);
	document.body.appendChild(link);
	link.click();
	document.body.removeChild(link);
}

/**
 * 判断主店同步是否启用
 */
export function isSyncStatus() {
	let userInfo = ref(JSON.parse(localStorage.getItem('userInfo') || '{}'))
	if (userInfo.value.isHeadShop == 0 && userInfo.value.isEnableProdSync == 1 && userInfo.value.isEnableVipSync == 1 && userInfo.value.isEnableConsSync == 1) {
		return true
	} else {
		return false
	}
}

/**
 * 判断是否有某权限
 */
export function hasPermission(params: any) {
	let $PermissionObj = JSON.parse(localStorage.getItem("permission") || '[]')
	const obj = $PermissionObj.find((v: any) => v == params || v == params)
	if (obj) {
		return obj
	}
	return false
}

/**
 * 过滤输入，只允许数字和最多两位小数
 * @param {string} value - 输入框当前值
 * @param {boolean} isIntegerOnly - 是否只允许正整数（无小数点），开启时最小值为1
 * @returns {string} 过滤后的合法值
 */
export function filterNumberInput(value, isIntegerOnly = false) {
	// 第一步就过滤所有非数字和非小数点的字符（包括字母）
	let filtered = value.replace(/[^\d.]/g, "");

	// 整数模式处理
	if (isIntegerOnly !== false) {
		// 移除所有小数点
		filtered = filtered.replace(/\./g, "");

		// 处理前导零
		filtered = filtered.replace(/^0+(\d)/, "$1") || filtered;

		// 空值处理（允许临时删除）
		if (filtered === "") {
			return "";
		}

		// 最小值限制
		if (filtered === isIntegerOnly || parseInt(filtered, 10) < isIntegerOnly) {
			return isIntegerOnly;
		}

		return filtered;
	}

	// 小数模式处理
	const parts = filtered.split(".");
	if (parts.length > 1) {
		filtered = parts[0] + "." + (parts[1].substring(0, 2) || "");
	}

	// 处理前导零
	if (filtered.startsWith("0") && filtered.length > 1 && !filtered.startsWith("0.")) {
		filtered = filtered.replace(/^0+(\d)/, "$1");
	}

	return filtered;
}

/**
 * 将时分秒字符串转换为完整日期格式
 * @param {string} timeStr - 时分秒字符串，格式需为 HH:mm:ss（如 '00:53:00'）
 * @param {Object} options - 可选配置项
 * @param {string} [options.customDate] - 自定义日期，格式为 YYYY-MM-DD（默认使用当前日期）
 * @param {string} [options.format='YYYY-MM-DD HH:mm:ss'] - 输出的日期格式
 * @returns {string|null} 转换后的日期字符串，失败时返回 null
 */
export function convertTimeToDate(timeStr, options = {}) {
	// 解构配置项，设置默认值
	const { customDate, format = "YYYY-MM-DD HH:mm:ss" } = options;

	// 1. 校验时分秒格式（必须为 HH:mm:ss，允许数字1-2位）
	const timeRegex = /^\d{1,2}:\d{1,2}:\d{1,2}$/;
	if (!timeRegex.test(timeStr)) {
		console.error("时分秒格式错误，请使用 HH:mm:ss 格式（如 00:53:00）");
		return null;
	}

	// 2. 确定日期部分（自定义日期或当前日期）
	let datePart;
	if (customDate) {
		// 校验自定义日期格式
		if (!dayjs(customDate, "YYYY-MM-DD", true).isValid()) {
			console.error("自定义日期格式错误，请使用 YYYY-MM-DD 格式（如 2024-05-20）");
			return null;
		}
		datePart = customDate;
	} else {
		// 使用当前日期（格式：YYYY-MM-DD）
		datePart = dayjs().format("YYYY-MM-DD");
	}

	// 3. 组合日期和时分秒，生成完整日期对象
	const fullDateTime = `${datePart} ${timeStr}`;
	const dateObj = dayjs(fullDateTime);

	// 4. 校验完整日期是否有效（如避免 2024-02-30 这种无效日期）
	if (!dateObj.isValid()) {
		console.error("生成的日期无效，请检查日期或时分秒是否合理");
		return null;
	}

	// 5. 按指定格式返回日期字符串
	return dateObj.format(format);
}

/**
 * 乘法计算并格式化结果
 * @param {string|number} num1 - 第一个乘数
 * @param {string|number} num2 - 第二个乘数
 * @returns {string} 保留两位小数的结果（不四舍五入，补零）
 */
export const multiplyAndFormat = (num1: any, num2: any = 1): string => {
	try {
		// 转换为BigNumber（使用字符串构造避免精度问题）
		const bigNum1 = new BigNumber(num1.toString());
		const bigNum2 = new BigNumber(num2.toString());

		// 1. 乘法计算
		const product = bigNum1.multipliedBy(bigNum2);

		// 2. 截断到两位小数（不四舍五入）
		const truncated = product.decimalPlaces(2, BigNumber.ROUND_DOWN);

		// 3. 格式化保留两位小数（补零）
		return truncated.toFixed(2);
	} catch (error) {
		console.error('计算错误:', error);
		return '0.00'; // 出错时返回默认值
	}
};

/**
 * 判断目标值是否包含指定字符串
 * @param {string|number|array} target - 目标值（字符串/数字/数组）
 * @param {string} searchStr - 要查找的子字符串
 * @param {object} [options] - 可选配置
 * @param {boolean} [options.ignoreCase=false] - 是否忽略大小写
 * @param {boolean} [options.allowEmpty=false] - 当 searchStr 为空时，是否返回 true（默认 false）
 * @returns {boolean} 是否包含指定字符串
 */
export function includesString(target, searchStr, options = {}) {
	// 解构配置，设置默认值
	const { ignoreCase = false, allowEmpty = false } = options;

	// 1. 处理 searchStr 为空的情况
	if (searchStr === '' || searchStr === null || searchStr === undefined) {
		return allowEmpty;
	}

	// 2. 统一将目标值转为字符串（兼容数字/数组等）
	let targetStr = '';
	if (typeof target === 'string') {
		targetStr = target;
	} else if (typeof target === 'number') {
		targetStr = String(target);
	} else if (Array.isArray(target)) {
		// 数组：拼接为字符串（也可改为 "数组中某一项包含"，根据需求调整）
		targetStr = target.join(',');
	} else {
		// 其他类型（对象/布尔等）：转为字符串或返回 false
		targetStr = String(target);
	}

	// 3. 处理大小写忽略
	const processedTarget = ignoreCase ? targetStr.toLowerCase() : targetStr;
	const processedSearch = ignoreCase ? searchStr.toLowerCase() : searchStr;

	// 4. 执行包含判断
	return processedTarget.includes(processedSearch);
}

/**
 * 校验手机号码（中国大陆）
 * - 支持 11 位手机号，号段 13x-19x
 * @param {string} phone
 * @returns {boolean}
 */
export function isValidMobile(phone: string): boolean {
	if (!phone && phone !== 0) return false;
	const s = String(phone).trim();
	// 中国大陆手机号正则：以1开头，第二位3-9，后面9位数字，总共11位
	const mobileRegex = /^1[3-9]\d{9}$/;
	return mobileRegex.test(s);
}

/**
 * 手机号脱敏：隐藏中间四位数字
 * @param {string | number} phone - 原始手机号（支持数字/字符串）
 * @returns {string} 脱敏后的手机号，如 138****1234
 */
export function maskPhone(phone) {
	// 先转成字符串，避免传入数字类型报错
	const phoneStr = String(phone).trim();

	// 简单校验：必须是11位数字
	if (!/^1\d{10}$/.test(phoneStr)) {
		console.warn('手机号格式不正确');
		return phoneStr; // 格式错误直接返回原值
	}

	// 核心：前3位 + **** + 后4位
	return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}

/**
 * 金额保留两位小数 不四舍五入
 * @param {number} num 金额数字
 * @param {boolean} hasSymbol 是否带¥符号，默认true
 * @returns {string}
 */
export function formatMoney(num, hasSymbol = true) {
	// 防止非数字、空值报错
	if (isNaN(Number(num))) num = 0;
	// 不四舍五入截断两位小数
	const value = Math.floor(Math.abs(num) * 100) / 100;
	// 拼接两位小数
	const fixedNum = value.toFixed(2);
	// 负数处理
	const result = num < 0 ? `-${fixedNum}` : fixedNum;
	// 默认返回带¥
	return hasSymbol ? `¥${result}` : result;
}
