const util = {}
import t from './test.js'
import i18n from '@/lang/lang.js'

/**
 * 检查邮箱格式
 * @param {string} str 要验证的邮箱
 */
util.checkmail = function(str) {
	let reg = t.isEmail
	if (!reg.test(str)) {
		return false
	} else {
		return true
	}
}

/**
 * 验证银行卡
 * @param {string} cardno 验证银行卡
 */
util.checkBankCard = function(cardno) {
	let reg = t.bankCard
	if (!reg.test(cardno)) {
		return false
	} else {
		return true
	}
}

/**
 * 设置页面原生标题
 * @param {string} title 页面标题名称
 */
util.setPageTitle = function(title) {
	let timer = null
	if (timer) timer = null
	timer = setTimeout(() => {
		uni.setNavigationBarTitle({
			title
		})
		timer = null
	}, 40)
}

/**
 * 判断数字是否正整数
 */
util.isCount = function(num) {
	if (t.isCount.test(num)) {
		return true
	} else {
		return false
	}
}

/**
 * 显示加载框
 */
util.showLoading = function(title, type) {
	// #ifdef APP-PLUS
	var w = plus.nativeUI.showWaiting(title || "", {
		width: '80px',
		height: '80px',
		loading: {
			type: type || 'snow',
			height: '40px'
		},
		background: 'rgba(0,0,0,0.9)'
	});
	// #endif
	// #ifndef APP-PLUS
	uni.showLoading({
		title: title || '',
	});
	// #endif
}


/**
 * 隐藏加载框
 */
util.hideLoading = function() {
	// #ifdef APP-PLUS
	plus.nativeUI.closeWaiting();
	// #endif
	// #ifndef APP-PLUS
	uni.hideLoading();
	// #endif
}

/**
 * 要复制的内容
 * NJS设置剪切板
 */
util.setClipboardData = function(string, callback) {
	const appPlatform = uni.getSystemInfoSync().platform
	// #ifdef APP-PLUS
	if (appPlatform == "ios") {
		var UIPasteboard = plus.ios.importClass("UIPasteboard");
		var generalPasteboard = UIPasteboard.generalPasteboard();
		// 设置 
		generalPasteboard.setValueforPasteboardType(string, "public.utf8-plain-text");
		callback && callback({
			code: 1
		});
	} else {
		var Context = plus.android.importClass("android.content.Context");
		var main = plus.android.runtimeMainActivity();
		var clip = main.getSystemService(Context.CLIPBOARD_SERVICE);
		plus.android.invoke(clip, "setText", string);
		callback && callback({
			code: 1
		});
	}
	// #endif
}

/**
 * njs 获取剪切板
 */
util.getClipboardData = function(callback) {
	const appPlatform = uni.getSystemInfoSync().platform
	// #ifdef APP-PLUS
	if (appPlatform == "ios") {
		var UIPasteboard = plus.ios.importClass("UIPasteboard");
		var generalPasteboard = UIPasteboard.generalPasteboard();
		// 获取 
		var value = generalPasteboard.valueForPasteboardType("public.utf8-plain-text");
		callback && callback({
			code: 1,
			data: value
		});
	} else {
		var Context = plus.android.importClass("android.content.Context");
		var main = plus.android.runtimeMainActivity();
		var clip = main.getSystemService(Context.CLIPBOARD_SERVICE);
		var value = plus.android.invoke(clip, "getText");
		callback && callback({
			code: 1,
			data: value
		});
	}
	// #endif
}

/**
 * 复制插件
 * params:
 * content 要复制的内容
 * success
 * error
 */
util.copy = function({
	content,
	success,
	error
}) {
	if (!content) return error('复制的内容不能为空 !')
	content = typeof content === 'string' ? content : content.toString() // 复制内容，必须字符串，数字需要转换为字符串
	/**
	 * 小程序端 和 app端的复制逻辑
	 */
	//#ifndef H5
	uni.setClipboardData({
		data: content,
		success: function() {
			success("复制成功~")
			console.log('success');
		},
		fail: function() {
			success("复制失败~")
		}
	});
	//#endif

	/**
	 * H5端的复制逻辑
	 */
	// #ifdef H5
	if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断
		// 不支持
		error('浏览器不支持')
	}
	let textarea = document.createElement("textarea")
	textarea.value = content
	textarea.readOnly = "readOnly"
	document.body.appendChild(textarea)
	textarea.select() // 选择对象
	textarea.setSelectionRange(0, content.length) //核心
	let result = document.execCommand("copy") // 执行浏览器复制命令
	if (result) {
		success("复制成功~")
	} else {
		error("复制失败，请检查h5中调用该方法的方式，是不是用户点击的方式调用的，如果不是请改为用户点击的方式触发该方法，因为h5中安全性，不能js直接调用！")
	}
	textarea.remove()
	// #endif
}

/**
 * 小程序获取摄像头权限
 */
util.cameraScan = function(callback) {
	uni.authorize({
		scope: 'scope.camera',
		success() {
			uni.scanCode({
				onlyFromCamera: true,
				scanType: ['barCode'],
				success: function(data) {
					callback && callback({
						data
					})
				}
			});
		},
		fail(e) {
			uni.showModal({
				content: '当前摄像头未授权该小程序，是否去授权？',
				success: function(res) {
					if (res.confirm) {
						// #ifdef MP-WEIXIN
						uni.openSetting({
							success(res) {
								if (res.authSetting['scope.camera']) {
									uni.showToast({
										title: '已授权',
										icon: 'success'
									});
								}
							}
						});
						// #endif
					}
				}
			});
		}
	});
}

/**
 * 小程序获取位置权限
 */
util.localtion = function(callback) {
	uni.authorize({
		scope: 'scope.userLocation',
		success() {
			return true
		},
		fail(e) {
			uni.showModal({
				content: '定位未授权该小程序，是否去授权？',
				success: function(res) {
					if (res.confirm) {
						// #ifdef MP-WEIXIN
						uni.openSetting({
							success(res) {
								if (res.authSetting['scope.userLocation']) {
									uni.showToast({
										title: '已授权',
										icon: 'success'
									});
									return true
								}
							}
						});
						// #endif
					} else {
						return false
					}
				}
			});
		}
	});
}

/**
 * 提示消息
 * @param {Object} msg
 */
util.showToast = function(msg, type = 'none', path) {
	uni.showToast({
		title: msg,
		mask: true,
		duration: 2000,
		icon: type
	});
}

/**
 * 字数过长，则超出部分用省略号显示
 * @param {String} str 当前要处理的字符串
 * @param {Number} len 显示的预期长度（字数）
 */
util.cutString = function(str, len) {
	//length属性读出来的汉字长度为1 
	if (str.length * 2 <= len) {
		return str;
	}
	var strlen = 0;
	var s = "";
	for (var i = 0; i < str.length; i++) {
		s = s + str.charAt(i);
		if (str.charCodeAt(i) > 128) {
			strlen = strlen + 2;
			if (strlen >= len) {
				return s.substring(0, s.length - 1) + "...";
			}
		} else {
			strlen = strlen + 1;
			if (strlen >= len) {
				return s.substring(0, s.length - 2) + "...";
			}
		}
	}
	return s
}

/**
 * 提取数组对象中某个键值，重新组成新的数组
 * @param {Array} arr 当前要处理的数组
 * @param {String} prop 要提取的键
 * return 返回新的数组
 */
util.extractProps = function(arr, prop) {
	return arr.map((item) => item[prop]);
}

/**
 * 判断某个变量的值是否为数字类型
 * @param {any} value 当前要判读的值
 * return 返回布尔类型 true 为数字，false 为非数字
 */
util.isNumber = function(value) {
	return typeof value === 'number' && !isNaN(value);
}

/**
 * 四舍五入保留2为小数，不够2为小数补0
 * @param {Number/String} value 当前的值
 * * @param {Number/String} type 是否四舍五入 floor：不； round：是
 * return 返回字符串 如10.00
 */
util.float = function(value, type = 'round') {
	var value = Math[type](parseFloat(value) * 100) / 100;
	var s = value.toString().split(".");
	if (s.length == 1) {
		value = value.toString() + ".00";
		return value;
	}
	if (s.length > 1) {
		if (s[1].length < 2) {
			value = value.toString() + "0";
		}
		return value;
	}
}

/**
 * 深度判断2个对象是否完全相等
 * @param {Object} x 当前要判读的第一个对象
 * @param {Object} y 当前要判读的第二个对象
 * return 返回布尔类型 true 为相等，false 为不相等
 */
util.deepCompare = function(x, y) {
	var i, l, leftChain, rightChain;

	function compare2Objects(x, y) {
		var p;
		if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
			return true;
		}
		if (x === y) {
			return true;
		}
		if ((typeof x === 'function' && typeof y === 'function') ||
			(x instanceof Date && y instanceof Date) ||
			(x instanceof RegExp && y instanceof RegExp) ||
			(x instanceof String && y instanceof String) ||
			(x instanceof Number && y instanceof Number)) {
			return x.toString() === y.toString();
		}
		if (!(x instanceof Object && y instanceof Object)) {
			return false;
		}
		if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
			return false;
		}
		if (x.constructor !== y.constructor) {
			return false;
		}
		if (x.prototype !== y.prototype) {
			return false;
		}
		if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
			return false;
		}
		for (p in y) {
			if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
				return false;
			} else if (typeof y[p] !== typeof x[p]) {
				return false;
			}
		}
		for (p in x) {
			if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
				return false;
			} else if (typeof y[p] !== typeof x[p]) {
				return false;
			}
			switch (typeof(x[p])) {
				case 'object':
				case 'function':
					leftChain.push(x);
					rightChain.push(y);

					if (!compare2Objects(x[p], y[p])) {
						return false;
					}

					leftChain.pop();
					rightChain.pop();
					break;
				default:
					if (x[p] !== y[p]) {
						return false;
					}
					break;
			}
		}
		return true;
	}
	if (arguments.length < 1) {
		return true;
	}
	for (i = 1, l = arguments.length; i < l; i++) {
		leftChain = [];
		rightChain = [];
		if (!compare2Objects(arguments[0], arguments[i])) {
			return false;
		}
	}
	return true;
}

/**
 * 判断数组中所有元素是否完全相同
 * @param {Array} array 当前数组
 * return 返回布尔类型 true 为全相同，false 为不全相同
 */
util.isAllEqual = function(array) {
	if (array.length > 0) {
		return !array.some(item => item !== array[0]);
	} else {
		return true
	}
}

/**
 * 数据分组
 * @param {Array} oArr - 原数组列表
 * @param {Number} length - 单个数组长度
 * @return {Array}  arr - 分组后的新数组
 */
util.splitData = function(oArr = [], length = 1) {
	let arr = [];
	let minArr = [];
	oArr.forEach(c => {
		if (minArr.length === length) {
			minArr = [];
		}
		if (minArr.length === 0) {
			arr.push(minArr);
		}
		minArr.push(c);
	});

	return arr;
}

/**
 * 剩余时间格式化
 * @param {Number} t - 剩余多少秒
 * @return {Object}  format - 格式后的天时分秒对象
 */
util.format = function(t) {
	let format = {
		d: '00',
		h: '00',
		m: '00',
		s: '00'
	};
	if (t > 0) {
		let d = Math.floor(t / 86400);
		let h = Math.floor((t / 3600) % 24);
		let m = Math.floor((t / 60) % 60);
		let s = Math.floor(t % 60);
		format.d = d < 10 ? '0' + d : d;
		format.h = h < 10 ? '0' + h : h;
		format.m = m < 10 ? '0' + m : m;
		format.s = s < 10 ? '0' + s : s;
	}
	return format;
}

/**
 * 打电话
 * @param {String<Number>} phoneNumber - 数字字符串
 */
util.callPhone = function(phoneNumber = '') {
	let num = phoneNumber.toString()
	uni.makePhoneCall({
		phoneNumber: num,
		fail(err) {
			console.log('makePhoneCall出错', err)
		},
	});
}

/**
 * 号码部分数字*代替
 * @param {String<Number>} str - 要进行隐藏的变量
 * @param {String<Number>} frontLen - 前面需要保留几位，默认前2位
 * @param {String<Number>} endLen - 后面需要保留几位，默认后2位
 */
util.hiddenCardId = function (str, frontLen = 2, endLen = 2) {
	let len = str.length - frontLen - endLen;
	let start = '';
	for (let i = 0; i < len; i++) {
		start += '*';
	}
	// 最后的返回值由三部分组成
	return str.substring(0, frontLen) + start + str.substring(str.length - endLen);
}

/**
 * 节流
 * 在给定时间内只有第一次的操作会返回结果
 * 结合了防抖的思路：在delay时间内生成定时器，一旦到了delay的时间就返回结果
 * 当用户只点击了一次的时候，在delay时间后得到结果
 * 当用户点击了多次的时候，在delay时间后得到第一次的结果，其余的被节流阀忽视掉
 * @param {Function} fn 要包装的回调函数
 * @param {number} delay 延迟时间，单位ms，默认500
 * @return {Function} 被节流函数劫持的新的函数
 */

util.throttle = function (fn, delay = 500) {
  let last = 0;
  let timer = null;
  
  return function () { 
    let args = arguments;
    let now = +new Date();
    let context = this;
    
    if (now - last < delay) {
      clearTimeout(timer);
      timer = setTimeout(() => {
        last = now;
        fn.apply(context, args);
      }, delay);
    } else {
        last = now;
        fn.apply(context, args);
    }
  }
}

/**
 * 防抖
 * 在delay时间后得到结果
 * 如果没等到delay的时间一直触发则永远也得不到结果
 * @param {Function} fn 要包装的回调函数
 * @param {number} delay 延迟时间，单位ms，默认500
 * @return {Function} 被防抖函数劫持的新的函数
 */
util.debounce = function (fn, delay = 500) {
  let timer = null;
  return function () {
    let args = arguments;

    if(timer) {
        clearTimeout(timer);
    }
    
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  }
}

export default util
