/**
 * # common.js 代码问题深度批判
## 代码结构：混乱不堪的功能堆砌
1. 模块化缺失 ：整个文件长达647行，包含了46个导出函数，从登录认证到时间格式化，从页面跳转到底层工具，所有功能混杂在一起，严重违反单一职责原则。这种"一锅炖"的设计导致代码难以维护和测试。
2. 函数组织无序 ：相关功能没有分组，例如登录相关的 toLogin 、 isLogin 、 saveLogin 等函数散布在文件不同位置，增加了代码阅读和理解的难度。
3. 命名规范混乱 ：函数命名风格不一致，有的使用驼峰命名（如 navigateTo ），有的使用下划线风格（如 cmsGetList ），甚至存在 modelShow 这样的混合命名，严重影响代码可读性。
## 安全性：漏洞百出的实现
1. 认证机制薄弱 ： isLogin 函数（48-66行）仅检查本地存储中是否存在用户数据，没有验证登录状态的有效性，容易被伪造登录状态。
2. URL处理存在风险 ： toUrl 函数（378-407行）对外部链接的处理过于简单，没有进行严格的URL格式验证和安全过滤，可能导致XSS攻击或恶意URL执行。
3. 本地存储安全隐患 ： saveLogin 函数（414-421行）直接将用户认证信息存储在本地，没有任何加密措施，一旦设备被破解，用户信息将直接泄露。
4. 密码处理缺失 ：代码中完全没有密码加密相关的逻辑，登录凭证的安全性无法保障。
## 性能：低效冗余的实现
1. 不必要的延迟 ： initPages 函数（334-372行）中存在硬编码的1秒延迟（366行 setTimeout(() => { ... }, 1000); ），没有任何合理的业务逻辑支持，纯粹浪费用户时间。
2. 重复的正则表达式创建 ： testString 函数（475-501行）和 checkMobile 函数（556-558行）每次调用都创建新的正则表达式对象，造成性能损耗，应该将正则表达式提升为模块级常量。
3. 网络请求冗余 ： initPages 函数在有缓存的情况下仍然会发起网络请求，没有实现有效的缓存策略，增加了服务器负担和用户等待时间。
4. 内存泄漏风险 ：多处使用 setTimeout 但没有清理机制，特别是在 modelShow 函数中，可能导致回调函数无法及时释放。
## 逻辑：错误百出的实现
1. 函数功能与命名不符 ： userInfo 函数（562-569行）返回的是 auth 对象而不是用户信息，与函数名严重不符，容易误导调用者。
2. 条件判断逻辑错误 ： isArray 函数（178-180行）的实现 return object && typeof object === 'object' 是错误的，因为对象和null也会返回true，正确的实现应该是 Array.isArray(object) 。
3. 导航逻辑混乱 ： navigateBack 函数（222-253行）包含大量硬编码的路由判断，逻辑复杂且难以维护，一旦路由结构变化，就需要修改多处代码。
4. 错误处理不完善 ：多处API调用（如 api.login 、 api.uploadImage ）只处理了成功情况，没有捕获和处理网络错误或服务器异常，可能导致程序崩溃。
## 代码质量：粗制滥造的实现
1. 硬编码泛滥 ：代码中存在大量硬编码值，如 cmsGetList 中硬编码的 /uploads/ 路径（287行）， toLogin 中硬编码的登录提示信息（19行）等，这些值应该通过配置文件管理。
2. 注释与代码不符 ： isLogin 函数的注释（46-47行）声称"是否登陆，和绑定手机号，否则返回登录页"，但实际代码中绑定手机号的逻辑被注释掉了（53-57行），注释与实现严重不符。
3. 冗余代码 ： testString 函数中 case null 分支（482-484行）直接返回false，没有任何实际作用，属于冗余代码。
4. 缩进与格式混乱 ：代码缩进不一致，有时使用空格，有时使用制表符，部分代码行尾存在多余的空格，影响代码可读性。
## 架构设计：过时落后的方案
1. 回调地狱 ：多处使用嵌套回调函数（如 initPages 、 cmsGetList ），没有使用Promise或async/await，导致代码可读性差，错误处理困难。
2. 全局依赖 ：直接导入 db 、 api 等模块，没有使用依赖注入，增加了模块间的耦合度，难以进行单元测试。
3. 平台兼容性处理粗糙 ：使用条件编译（如 #ifdef H5 、 #ifdef MP ）处理不同平台的差异，但逻辑分散在各个函数中，没有统一的平台适配层。
4. 缺乏错误边界 ：整个代码库没有统一的错误处理机制，每个函数都需要单独处理错误，增加了代码复杂度和维护成本。
## 总结
这份 common.js 代码是一个典型的"代码坏味道"集合体，从架构设计到具体实现，从安全性到性能，几乎每一个方面都存在严重问题。它反映了开发过程中的敷衍了事和缺乏专业素养，是前端代码质量的反面教材。

这样的代码不仅会增加开发和维护成本，还会给应用带来严重的安全隐患和性能问题。如果不进行彻底重构，随着项目规模的扩大，这些问题将会像滚雪球一样越积越多，最终导致整个应用崩溃或被黑客攻击。

作为一名专业的开发者，应该严格遵循代码规范和最佳实践，注重代码质量和安全性，而不是像这样随意堆砌功能。这份代码的存在，本身就是对软件工程这门学科的不尊重。
 *
 */

import * as db from './db.js' //引入common
import * as api from './api.js'
import {
	baseUrl,
	cndUrl,
	bgClass,
	title,
	baseLogo,
} from './config.js'
import htmlParser from '@/common/html-parser' //引入htmlParser


/**
 * 跳转登陆页面
 */
function toLogin() {

	uni.showToast({
		title: '请登录...',
		icon: 'loading',
		duration: 2000,
		success: function(res) {
			var pages = getCurrentPages() // 获取栈实例
			let currentRoute = pages[pages.length - 1].route; // 获取当前页面路由
			//console.log("路由当前页面路径"+currentRoute)
			let currentPage = pages[pages.length - 1]['$page']['fullPath'] //当前页面路径(带参数)
			// console.log(currentPage)

			// #ifdef H5 || APP-PLUS
			uni.navigateTo({
				url: '/pages/user/login?redirect=' + escape(currentPage)
			})
			// #endif
			// #ifdef MP-WEIXIN
			uni.navigateTo({
				url: '/pages/user/login?redirect=' + escape(currentPage),
				animationType: 'pop-in',
				animationDuration: 200
			});
			// #endif
		}
	})
}

/**
 * 是否登陆，和绑定手机号，否则返回登录页
 */
function isLogin() {
	let user = db.get('user');
	//用户存在，不跳转，不存在直接跳转
	if (user) {
		if (user.id) {
			// if(user.mobile==''){
			// 	uni.navigateTo({
			// 		url: '/pages/user/bind'
			// 	})
			// }	

		} else {
			console.log("user: ", user);
			db.del('user');
			db.del('auth');
			toLogin()
		}
	}
}
/**
 * 无图标提示
 * @param {String} msg 提示消息
 * @param {Function} callback 回调函数
 */

function normalToShow(msg = '保存成功', callback = function() {}) {
	uni.showToast({
		title: msg,
		icon: 'none',
		duration: 2000,
	});
	setTimeout(function() {
		callback();
	}, 1000);
}
/**
 * 成功提示
 * @param {String} msg 提示消息
 * @param {Function} callback 回调函数
 */

function successToShow(msg = '保存成功', callback = function() {}) {
	uni.showToast({
		title: msg,
		icon: 'success',
		duration: 2000,
	});
	setTimeout(function() {
		callback();
	}, 1500);
}

/**
 * 失败提示
 * @param {String} msg 提示消息
 * @param {Function} callback 回调函数
 */

function errorToShow(msg = '操作失败', callback = function() {}) {
	uni.showToast({
		title: msg,
		icon: 'none',
		duration: 2000,
	});
	setTimeout(function() {
		callback();
	}, 2000);
}

/**
 * 加载显示
 * @param {String} msg 提示消息
 */
function loadToShow(msg = '加载中', icon = 'loading') {
	uni.showToast({
		title: msg,
		icon: icon,
	});
}

/**
 * 加载隐藏
 */

function loadToHide() {
	uni.hideToast();
}

/**
 * 提示框
 * @param {String} title 提示标题
 * @param {String} content 提示内容
 * @param {Function} callback 回调函数
 * @param {Boolean} showCancel = [true|false] 显示关闭按钮
 * @param {String} cancelText 关闭按钮文字 
 * @param {String} confirmText 确定按钮文字 
 * @example
 * modelShow('提示','确认执行此操作吗?',()=>{},()=>{},true,'取消','确定')
 */
function modelShow(title = '提示', content = '确认执行此操作吗?', callback = () => {}, callback2 = () => {}, showCancel = true,
	cancelText = '拒绝',
	confirmText = '通过') {
	uni.showModal({
		title: title,
		content: content,
		showCancel: showCancel,
		cancelText: cancelText,
		confirmText: confirmText,
		success: function(res) {
			if (res.confirm) {
				// 用户点击确定操作
				setTimeout(() => {
					callback()
				}, 500)
			} else if (res.cancel) {
				// 用户取消操作
				setTimeout(() => {
					callback2()
				}, 500)
			}
		}
	});
}



/**
 * 判断数组
 * @param {Object} arr 数组
 */
function isArray(object) {
	return object && typeof object === 'object'
}

/**
 * 统一跳转
 * @param {String} url 跳转链接
 */
function navigateTo(url) {
	if (url == '')
		return;
	if (url.indexOf("/pages/index/index") >= 0 || url.indexOf("answer_pages/home/dashboard") >= 0 || url.indexOf(
			"/pages/shouhu/shouhu") >= 0 || url.indexOf("/pages/feiyi/feiyi") >= 0 || url.indexOf(
			"/pages/user/index") >= 0) {
		uni.switchTab({
			url: url,
			animationType: 'pop-in',
			animationDuration: 300
		});
	} else {
		uni.navigateTo({
			url: url,
			animationType: 'pop-in',
			animationDuration: 300
		});
	}

}

/**
 * 关闭当前页面并跳转
 * @param {String} url 跳转链接
 */
function redirectTo(url) {
	uni.redirectTo({
		url: url,
		animationType: 'pop-in',
		animationDuration: 300
	})
}
/**
 * 返回上一层的逻辑判断
 * @param {num} delta 跳转上一层，或者几层
 */
function navigateBack(delta = 1) {
	let pages = getCurrentPages(); //当前页
	//console.log(pages);
	//当有前一页的时候。
	if (pages.length > 1) {
		let page = pages[pages.length - 2]; //上个页面
		// console.log(page.route);
		if (page.route == "pages/index/index" || page.route == 'pages/index/homepage' || page.route ==
			'pages/user/index' || page.route == 'pages/consult/index') {
			uni.switchTab({
				url: '/' + page.route
			})
		} else if (page.route == "pages/user/login") {
			uni.switchTab({
				url: '/pages/user/index'
			})
		} else if (page.route == "pages/user/register") {
			uni.switchTab({
				url: '/pages/user/user'
			})
		} else {
			uni.navigateBack({
				delta: delta
			})
		}
	} else {
		uni.switchTab({
			url: '/pages/index/index'
		})
	}

}

/**
 *  判断是否在微信浏览器
 */
function isWeiXinBrowser() {
	// #ifdef H5
	// window.navigator.userAgent属性包含了浏览器类型、版本、操作系统类型、浏览器引擎类型等信息，这个属性可以用来判断浏览器类型
	let ua = window.navigator.userAgent.toLowerCase()
	// 通过正则表达式匹配ua中是否含有MicroMessenger字符串
	if (ua.match(/MicroMessenger/i) == 'micromessenger') {
		return true
	} else {
		return false
	}
	// #endif

	// #ifdef MP
	return false;
	// #endif
}


/**
 * 加载cms列表
 * @param {Array} data
 * 
 */

function cmsGetList(data, callback = function() {}) {
	api.cmsGetList(data, res => {
		if (res.code) {
			res.data.list.forEach(function(ele, index) {
				ele.ctime = timeToDate(ele.createtime);
				if (ele.image.substring(0, 9) == '/uploads/') {
					ele.image = cndUrl + ele.image
				}
			});
			callback(res.data)
		} else {
			errorToShow(res.msg)
		}
	})
}


/**
 * 加载cms详情
 * @param {Array} data
 * 
 */

function cmsGetDetails(data, callback = function() {}) {
	api.cmsGetDetails(data, res => {
		//console.log(data)
		if (res.code) {
			res.data.content = htmlParser(res.data.content); //	设置资源cdn;
			res.data.ctime = timeToDate(res.data.createtime);
			if (res.data.image) {
				if (res.data.image.substring(0, 9) == '/uploads/') {
					res.data.image = cndUrl + res.data.image
				}
			}
			callback(res.data)
		} else {
			modelShow(
				'错误提示',
				res.msg,
				() => {
					uni.navigateBack({})
				},
				false
			);
		}
	})
}
/**
 * 初始化页面
 * @param {Function} callback 回调函数
 * @param {String} route	页面路径/默认当前路径
 */
function initPages(callback = function() {}, route) {

	if (!route) {
		let pages = getCurrentPages();
		let page = pages[pages.length - 1];
		route = page.route
	}
	let init_data = db.get('init_' + route)

	setTimeout(() => {
		api.getInit({
			route: route
		}, res => {
			// console.log(res);
			if (res.code) {

				res.data.slide.forEach(function(ele, index) {
					if (ele.image.substring(0, 9) == '/uploads/') {
						ele.image = cndUrl + ele.image
					}
				});
				res.data.content.forEach(function(ele, index) {
					ele.content = ele.content.replace(new RegExp(`style="width: 100%;`, 'g'),
						'style="width: 100%;margin-top: -3px;') //	无缝连接图片;
					ele.content = ele.content.replace(new RegExp(`src="/uploads`, 'g'),
						'src="' + cndUrl + '/uploads')
					ele.content = htmlParser(ele.content); //	设置资源cdn;
				});
				db.set('init_' + route, res.data)
				callback(res.data)
			}
		});
	}, 1000);
	if (init_data) {
		callback(init_data)
	} else {
		// loadToShow('初始化页面...');
	}
}

/**
 * 跳转链接
 * @param {String} url 跳转链接
 */
function toUrl(url) {
	if (url) {

		var objExp = new RegExp(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/);
		if (objExp.test(url) != true) {
			// #ifdef APP-PLUS
			url = baseUrl + url
			// #endif
			// #ifdef H5
			url = baseUrl + url
			// #endif
		}
		//console.log(url)
		//return false
		// #ifdef MP
		uni.navigateTo({
			url: url
		})
		// #endif

		// #ifdef APP-PLUS
		plus.runtime.openURL(url);
		// #endif

		// #ifdef H5
		window.open(url);
		// #endif

	}
}


/**
 * 保存登陆状态
 * @param {Array} data 用户数据
 */
function saveLogin(data) {
	db.set('auth', data.auth)

	if (data.user.avatar.substring(0, 9) == '/uploads/') {
		data.user.avatar = cndUrl + data.user.avatar
	}
	db.set('user', data.user)
}


/**
 * 刷新用户
 * @param {Function} callback 回调函数（用户数据）
 * @example 
 * refreshUser((user)=>{_this.user = user})
 */
function refreshUser(callback = function() {}) {
	let user = db.get('user');
	if (user.id) {
		api.refreshUser({}, res => {
			if (res.code == 1) {
				saveLogin(res.data)
				callback(res.data)
			} else {
				db.del('user');
				toLogin()
			}
		})
	} else {
		db.del('user');
		db.del('auth');
		toLogin()
	}
}



/**
 * 清理用户
 * @param {String} page 清理后跳转页面
 */
function cleanUser(page) {
	db.del('user')
	db.del('auth')
	if (page) {
		redirectTo(page)
	}
}




/**
 * 字符串校验
 * @param {String} str 字符串
 * @param {String} model = [number|mobile|name|idcard|] 模式
 * @example 
 * testString('17080057443','mobile')
 * testString('17080057443','mobile')
 */

function testString(str, model = null) {
	if (typeof(model) == 'number') {
		if (str.length >= model) {
			return true
		}
	} else {
		switch (model) {
			case null:
				return false
				break
			case 'idcard':
				return RegExp(/^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/)
					.test(str)
				break
			case 'mobile':
				return RegExp(/^1[0-9]{10}$/).test(str)
				break
			case 'name':
				return RegExp(/^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$/).test(str)
				break
			default:
				return false
				break
		}
	}
	return false
}




/**
 * 时间戳转时差
 * @param {String} date 时间戳
 */

function timeToDate(time) {
	time = time * 1000
	var interval = new Date().getTime() - time;
	//计算出相差天数
	var returnTime = "";
	var days = Math.floor(interval / (24 * 3600 * 1000))
	if (days == 0) {
		//计算出小时数
		var leaveTime = interval % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
		var hours = Math.floor(leaveTime / (3600 * 1000))
		if (hours == 0) {
			//计算相差分钟数
			leaveTime = leaveTime % (3600 * 1000) //计算小时数后剩余的毫秒数
			var minutes = Math.floor(leaveTime / (60 * 1000))
			if (minutes == 0) {
				//计算相差秒数
				leaveTime = leaveTime % (60 * 1000) //计算分钟数后剩余的毫秒数
				var seconds = Math.round(leaveTime / 1000)
				return seconds + "秒前";
			}
			return minutes + "分钟前";
		}
		return hours + "小时前";
	}
	return days + "天前";
}



/**
 * 基本信息
 */
function baseInfo() {
	return {
		bgClass: bgClass,
		title: title,
		baseLogo: baseLogo,
	}
}
//校验邮箱格式
function checkEmail(email) {
	return RegExp(/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/).test(
		email);
}
//校验手机格式
function checkMobile(mobile) {
	return RegExp(/^1[0-9]{10}$/).test(mobile);
}
/**
 * 用户信息
 */
function userInfo() {
	let user = db.get('auth')
	if (user) {
		return user
	} else {
		return false;
	}

	// return {
	// 	bgClass: bgClass,
	// 	title: title,
	// 	baseLogo: baseLogo,
	// }
}


/**
 * 上传图片
 * @param {Array} data 附带数据
 * @param {Function} callback 回调函数
 * @param {int} num 限制数量
 * @param {String} type 类型
 * @return {String} url 
 */
function uploadImage(data = {}, callback = function() {}, num = 1, type) {
	api.uploadImage(
		'common/upload', data, (res) => {
			if (res.code) {
				if (res.data.url.substring(0, 9) == '/uploads/') {
					res.data.url = cndUrl + res.data.url
				}
				callback(res.data.url)
			} else {
				errorToShow(res.msg)
			}
		}, type)

}

function formatRichText(html) {
	let newContent = html.replace(/<img[^>]*>/gi, function(match, capture) {
		match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
		match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
		match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
		return match;
	});
	newContent = newContent.replace(/style="[^"]+"/gi, function(match, capture) {
		match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;');
		return match;
	});
	newContent = newContent.replace(/<br[^>]*\/>/gi, '');
	newContent = newContent.replace(/\<img/gi, '<img style="max-width:100%;height:auto;display:block;margin:10px 0;"');
	return newContent;
}


export {
	toLogin,
	isLogin,
	normalToShow,
	successToShow,
	errorToShow,
	isArray,
	loadToShow,
	loadToHide,
	navigateTo,
	navigateBack,
	redirectTo,
	modelShow,
	isWeiXinBrowser,
	initPages,
	toUrl,
	saveLogin,
	refreshUser,
	cleanUser,
	testString,
	timeToDate,
	cmsGetList,
	cmsGetDetails,
	baseInfo,
	userInfo,
	uploadImage,
	checkEmail,
	checkMobile,
	formatRichText
}