/**
 * 心跳检测的JS
 * 系统下线 25 秒后，将无法提交文档到服务器
 * 检测到系统下线后，在关闭文档的时候会提醒，并自动开启重连
 * 添加自定义协议$reconnect 请求系统重连
 */
;(function () {
	const ACTIONS_WITHOUT_HEART = [
		'printdocument',
		'convertpdf',
		'convertofd',
		'saveAs',
	]
	const HEAR_OPEN_DOCS = 'HEAR_OPENED_DOCS'
	const OA_SYSTEM_ONLINE = 'OA_SYSTEM_ONLINE'
	const HEART_INTERVAL = 2e3 //心跳频率 和OA系统一致
	let retrycount = 5
	let reconnectHandler

	/**
	 * 设定已经打开的OA文档
	 * @param {wps.Document} obj
	 */
	function OpendOADocument(doc) {
		const fileinfo = GetDocParamsValue(doc, 'fileInfo')
		let uuid = getParamFormIndiDocxForm(fileinfo, 'file_unid')
		let name = getParamFormIndiDocxForm(fileinfo, 'file_name')
		let current = JSON.parse(wps.PluginStorage.getItem(HEAR_OPEN_DOCS) || '{}')

		var info = { uuid, name }
		current[GetUniqueId(doc)] = info
		wps.PluginStorage.setItem(HEAR_OPEN_DOCS, JSON.stringify(current))

		//反向重连
		Reconnect(info)
	}

	/**
	 * 关闭OA文档
	 * @param {*} uuid
	 */
	function CloseOADocument(doc) {
		let current = JSON.parse(wps.PluginStorage.getItem(HEAR_OPEN_DOCS) || '{}')
		let info = current[GetUniqueId(doc)]
		delete current[GetUniqueId(doc)]
		wps.PluginStorage.setItem(HEAR_OPEN_DOCS, JSON.stringify(current))
		loginfo(`${doc.Name}下线`)

		if (!!info)
			OAWebNotice(
				JSON.stringify({
					cmd: '$disconnect',
					type: ClientType,
					uuid: info.uuid,
					name: info.name,
				})
			) //发送重连信号
	}

	function GetCurrentDocs() {
		return JSON.parse(wps.PluginStorage.getItem(HEAR_OPEN_DOCS) || '{}')
	}

	function getDocHeart(doc) {
		return GetCurrentDocs()[GetUniqueId(doc)]
	}

	function OASystemOnLine(expried) {
		var next = expried || Date.now() + HEART_INTERVAL * 10
		wps.PluginStorage.setItem(OA_SYSTEM_ONLINE, next)

		wps.ribbonUI.Invalidate() //刷新Ribbon的状态
		//清理
		ClearReconnect()
	}

	/**
	 * OA系统是否在线
	 * @returns booleans
	 */
	function IsOASystemOnline(tryReconnect = false) {
		//ClientType in util.js
		if (OACustomer.getCustomerHeart(ClientType) === false) return true
		var online =
			Number(wps.PluginStorage.getItem(OA_SYSTEM_ONLINE)) > Date.now()

		if (!online && tryReconnect) {
			//启动主动请求重
			loginfo('系统下线,启动自动重连')
			reconnectHandler = setTimeout(Reconnect, 500)
		}
		wps.ribbonUI.Invalidate() //刷新Ribbon的状态
		return online
	}

	function Reconnect(info) {
		if (OACustomer.getCustomerHeart(ClientType) === false) return
		if (retrycount-- > 0) {
			loginfo('请求心跳')
			OAWebNotice(
				JSON.stringify({
					cmd: '$reconnect',
					type: ClientType,
					uuid: info.uuid,
					name: info.name,
				})
			) //发送重连信号
			reconnectHandler = setTimeout(function () {
				!IsOASystemOnline() && Reconnect(info)
			}, HEART_INTERVAL)
		} else {
			//请求5次后，重置
			retrycount = 5
		}
	}

	function ClearReconnect() {
		if (!!reconnectHandler) {
			loginfo('业务系统已重新连接')

			clearTimeout(reconnectHandler)
			reconnectHandler = null
		}
		retrycount = 5
	}

	window.Heart = {
		OpendOADocument,
		CloseOADocument,
		GetCurrentDocs,
		OASystemOnLine,
		IsOASystemOnline,
		getDocHeart,
		HEART_INTERVAL,
		ACTIONS_WITHOUT_HEART,
	}
})(window)

/**
 * 心跳
 * @returns
 */
function heart() {
	Heart.OASystemOnLine()
	var data = Heart.GetCurrentDocs() || {}
	return {
		message: 'ok',
		app: ClientType,
		docs: Object.values(data),
	}
}
