<script>
	import {mapGetters,mapActions} from "vuex";
	// #ifdef APP
	import IMSDK, {IMMethods,MessageType,SessionType,} from "openim-uniapp-polyfill";
	// #endif
	import config from "@/common/config";
	import {getDbDir,toastWithCallback} from "@/util/common.js";
	import {getConversationContent,conversationSort,prepareConversationState,updateTabbar} from "@/util/imCommon";
	import {PageEvents,UpdateMessageTypes} from "@/constant";
	import checkUpgrade from "@/util/app_update.js"
	export default {
		onLaunch: function() {
			this.$store.dispatch("system/getConfig");
			// #ifdef APP
			plus.screen.lockOrientation("portrait-primary");
			// #endif
			// #ifdef H5
			//screen.orientation.type = "";
			screen.orientation.lock('portrait');
			// #endif
			// #ifndef MP
			console.error(
				`暂时不支持运行到小程序端`
			);
			return ;
			// #endif
			this.init();
		},
		onShow: function() {
			//console.log("App Show");
			// #ifdef APP
			IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), false);
			// #endif
			this.handleArguments();
			//console.log(this.$store.state.contact);
		},
		onHide: function() {
			//console.log("App Hide");
			// #ifdef APP
			IMSDK.asyncApi(IMSDK.IMMethods.SetAppBackgroundStatus, IMSDK.uuid(), true);
			// #endif
		},
		computed: {
			...mapGetters([
				"storeConversationList",
				"storeCurrentConversation",
				"storeCurrentUserID",
				"storeSelfInfo",
				"storeRecvFriendApplications",
				"storeRecvGroupApplications",
				"storeHistoryMessageList",
				"storeIsSyncing",
				"storeGroupList",
				"config",
				'storeUnHandleFriendApplicationNum',
				'storeUnHandleGroupApplicationNum',
				'storeUnReadCount',
				'storeCircleUnreadCount'
			]),
		},
		watch:{
			storeUnReadCount(){
				updateTabbar(0);
			},
			storeUnHandleFriendApplicationNum(){
				updateTabbar(1);
			},
			storeUnHandleGroupApplicationNum(){
				updateTabbar(1);
			},
			storeCircleUnreadCount(){
				updateTabbar(2);
			}
		},
		methods: {
			...mapActions("message", ["pushNewMessage", "updateOneMessage"]),
			...mapActions("conversation", ["updateCurrentMemberInGroup"]),
			...mapActions("circle", ["getFriendCircleInfo"]),
			...mapActions("contact", [
				"updateFriendInfo",
				"pushNewFriend",
				"updateBlackInfo",
				"pushNewBlack",
				"pushNewGroup",
				"updateGroupInfo",
				"pushNewRecvFriendApplition",
				"updateRecvFriendApplition",
				"pushNewSentFriendApplition",
				"updateSentFriendApplition",
				"pushNewRecvGroupApplition",
				"updateRecvGroupApplition",
				"pushNewSentGroupApplition",
				"updateSentGroupApplition",
			]),
			init(){
				const IMToken = uni.getStorageSync("IMToken");
				const IMUserID = uni.getStorageSync("IMUserID")+'';
				if (IMToken && IMUserID) {
					// #ifdef APP
					this.tryLogin();
					// #endif
				}else{
					plus.navigator.closeSplashscreen();
					//uni.$u.route("/pages/common/login/index");
				}
			},
			setGlobalIMlistener() {
				//console.log("setGlobalIMlistener");
				// init
				const kickHander = (message) => {
					toastWithCallback(message, () => {
						uni.removeStorage({
							key: "IMToken",
						});
						uni.removeStorage({
							key: "BusinessToken",
						});
						uni.$u.route("/pages/common/login/index");
					});
				};
				//由于 APP 管理员强制用户下线，或由于登录策略导致用户被踢下线
				IMSDK.subscribe(IMSDK.IMEvents.OnKickedOffline, (data) => {
					kickHander("您的账号在其他设备登录，请重新登陆！");
				});
				//token无效回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenExpired, (data) => {
					kickHander("您的登录已过期，请重新登陆！");
				});
				IMSDK.subscribe(IMSDK.IMEvents.OnUserTokenInvalid, (data) => {
					kickHander("您的登录已无效，请重新登陆！");
				});
		
				// sync
				//向服务器同步会话开始时的回调。
				const syncStartHandler = ({data}) => {
					this.$store.commit("user/SET_IS_SYNCING", true);
					this.$store.commit("user/SET_REINSTALL", data);
				};
				//同步中
				const syncProgressHandler = ({data}) => {
					this.$store.commit("user/SET_PROGRESS", data);
				};
				//向服务器同步会话成功时的回调。
				const syncFinishHandler = () => {
					uni.hideLoading();
					this.$store.dispatch("conversation/getConversationList");
					this.$store.dispatch("contact/getFriendList");
					this.$store.dispatch("contact/getGrouplist");
					this.$store.dispatch("conversation/getUnReadCount");
					this.$store.commit("user/SET_IS_SYNCING", false);
				};
				//向服务器同步会话失败时的回调。
				const syncFailedHandler = () => {
					uni.hideLoading();
					uni.$u.toast("同步消息失败");
					this.$store.dispatch("conversation/getConversationList");
					this.$store.dispatch("conversation/getUnReadCount");
					this.$store.commit("user/SET_IS_SYNCING", false);
				};
				//向服务器同步会话开始时的回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerStart, syncStartHandler);
				//向服务器同步会话成功时的回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFinish, syncFinishHandler);
				//向服务器同步会话失败时的回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerFailed, syncFailedHandler);
				//同步中
				IMSDK.subscribe(IMSDK.IMEvents.OnSyncServerProgress, syncProgressHandler);
		
				// 当前登录用户个人信息改变时会收到此回调。
		
				IMSDK.subscribe(IMSDK.IMEvents.OnSelfInfoUpdated, ({data}) => {
					this.$store.commit("user/SET_SELF_INFO", {
						...this.storeSelfInfo,
						...data,
					});
				});
		
				// message
				//接收到新消息时会收到此回调，回调中只会携带一条消息。
				//设置了批量消息监听setBatchMsgListener时，此回调不会触发。
				//IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessage, ({data}) =>{});
				IMSDK.subscribe(IMSDK.IMEvents.OnRecvNewMessages, ({data}) => {
					if (this.storeIsSyncing) {
						return;
					}
					console.log(data);
					data.forEach(this.handleNewMessage);
				});
		
				//好友个人信息（包括备注）改变时会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendInfoChanged,({data}) => {
					//console.log('friendInfoChangeHandler',data);
					uni.$emit(IMSDK.IMEvents.OnFriendInfoChanged, {data});
					this.updateFriendInfo({friendInfo: data,});
				});
				//两个用户成功建立好友关系后双方都会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendAdded, ({data}) => {
					this.pushNewFriend(data);
				});
				//某个用户的好友列表减少时会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendDeleted, ({data}) => {
					this.updateFriendInfo({
						friendInfo: data,
						isRemove: true,
					});
				});
		
				// blacklist
				//某个用户的黑名单列表增加时会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnBlackAdded, ({data}) => {
					this.pushNewBlack(data);
				});
				//某个用户的黑名单列表减少时会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnBlackDeleted, ({data}) => {
					this.updateBlackInfo({
						blackInfo: data,
						isRemove: true,
					});
				});
		
				// group
				const joinedGroupAddedHandler = ({data}) => {
					this.pushNewGroup(data);
				};
				const joinedGroupDeletedHandler = ({data}) => {
					this.updateGroupInfo({
						groupInfo: data,
						isRemove: true,
					});
				};
				const groupInfoChangedHandler = ({data}) => {
					this.updateGroupInfo({
						groupInfo: data,
					});
				};
				const groupMemberInfoChangedHandler = ({data}) => {
					uni.$emit(IMSDK.IMEvents.OnGroupMemberInfoChanged, {data});
					if (data.groupID === this.storeCurrentConversation?.groupID) {
						this.updateCurrentMemberInGroup(data);
					}
				};
				//用户所在群组的数量增加时（被邀请入群、入群申请被同意等），会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupAdded,joinedGroupAddedHandler);
				//用户所在群组的数量减少时（主动退群、群被解散等），会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnJoinedGroupDeleted,joinedGroupDeletedHandler);
				//群组信息（头像、群名称等，也包括群主变化）改变时，该群所有群成员会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnGroupInfoChanged,groupInfoChangedHandler);
				//群成员信息改变（群昵称、头像等）后回调，该群所有群成员会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberInfoChanged,groupMemberInfoChangedHandler);
		
				// application
				const friendApplicationNumHandler = ({data}) => {
					const isRecv = data.toUserID === this.storeCurrentUserID;
					if (isRecv) {
						this.pushNewRecvFriendApplition(data);
					} else {
						this.pushNewSentFriendApplition(data);
					}
				};
				const friendApplicationAccessHandler = ({data}) => {
					console.log(data);
					const isRecv = data.toUserID === this.storeCurrentUserID;
					if (isRecv) {
						this.updateRecvFriendApplition({
							application: data,
						});
					} else {
						this.updateSentFriendApplition({
							application: data,
						});
					}
				};
				const groupApplicationNumHandler = ({data}) => {
					const isRecv = data.userID !== this.storeCurrentUserID;
					if (isRecv) {
						this.pushNewRecvGroupApplition(data);
					} else {
						this.pushNewSentGroupApplition(data);
					}
				};
				const groupApplicationAccessHandler = ({data}) => {
					const isRecv = data.userID !== this.storeCurrentUserID;
					if (isRecv) {
						this.updateRecvGroupApplition({
							application: data,
						});
					} else {
						this.updateSentGroupApplition({
							application: data,
						});
					}
				};
				//用户发起好友申请后，申请发起者和接收者都会收到此回调，接收者可以选择同意或拒绝好友申请。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAdded,friendApplicationNumHandler);
				//好友申请被同意时，申请发起方和接收方都会收到该回调，双方成功建立好友关系。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationAccepted,friendApplicationAccessHandler);
				//好友申请被拒绝时，申请发起方和接收方都会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnFriendApplicationRejected,friendApplicationAccessHandler);
				//用户发起好友申请后，申请发起者和接收者都会收到此回调，接收者可以选择同意或拒绝好友申请。
				IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAdded,groupApplicationNumHandler);
				//好友申请被同意时，申请发起方和接收方都会收到该回调，双方成功建立好友关系。
				IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationAccepted,groupApplicationAccessHandler);
				//好友申请被拒绝时，申请发起方和接收方都会收到该回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnGroupApplicationRejected,groupApplicationAccessHandler);
				//群组被解散时，该群所有群成员会收到此回调。
				//IMSDK.subscribe(IMSDK.IMEvents.OnGroupDismissed,({ data })=>{});
				//群成员增加（如用户被邀请进群），其他群成员会收到此回调。
				//IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberAdded,({ data })=>{});
				//群成员增加（如用户被邀请进群），群成员减少（如群成员退群）， 其他群成员会收到此回调。。
				//IMSDK.subscribe(IMSDK.IMEvents.OnGroupMemberDeleted,({ data })=>{});
				const deleteLocalMsg = (clientMsgID)=>{
					let list = this.storeHistoryMessageList;
					//console.log(data);
					list = list.filter((item)=>{
						return item.clientMsgID != clientMsgID;
					})
					this.$store.commit('message/SET_HISTORY_MESSAGE_LIST',list);
				}
				//收到的消息被撤回或自己发出的消息被撤回时，会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnNewRecvMessageRevoked,({data})=>{
					//console.log('onNewRecvMessageRevoked',res);
					deleteLocalMsg(data.clientMsgID);
				});
				//自己发出的单聊消息被对方标记为已读后，消息发送者会收到此回调。
				//IMSDK.subscribe(IMSDK.IMEvents.OnRecvC2CReadReceipt,({ data })=>{});
				//自己发出的群聊消息被群成员标记为已读后，消息发送者和标记者均会收到此回调。
				//IMSDK.subscribe(IMSDK.IMEvents.OnRecvGroupReadReceipt,({ data })=>{});
				//当应用在后台运行，接收到新消息时，会收到该回调，回调中只会携带一条消息。
				//设置了批量消息监听setBatchMsgListener时，此回调不会触发。
				//IMSDK.subscribe(IMSDK.IMEvents.OnRecvOfflineNewMessage,({ data })=>{});
				//当应用在后台运行，接收到新消息时，会收到该回调，回调中可能会携带多条消息。
				IMSDK.subscribe(IMSDK.IMEvents.OnRecvOfflineNewMessages,({data})=>{
					data.forEach(this.handleOfflineNewMessages);
				});
				IMSDK.subscribe(IMSDK.IMEvents.OnMsgDeleted,({data})=>{
					deleteLocalMsg(data.clientMsgID)
				});
				//已订阅用户的在线状态发生变化时，会触发此回调。
				//IMSDK.subscribe(IMSDK.IMEvents.OnUserStatusChanged,({ data })=>{});
				//建立WebSocket连接失败返回后，触发此回调
				//IMSDK.subscribe(IMSDK.IMEvents.OnConnectFailed,({ data })=>{});
				//建立WebSocket连接成功返回后，触发此回调
				//IMSDK.subscribe(IMSDK.IMEvents.OnConnectSuccess,({ data })=>{});
				//建立WebSocket连接中，触发此回调
				//IMSDK.subscribe(IMSDK.IMEvents.OnConnecting,({ data })=>{});
				//正在输入状态回调。
				//IMSDK.subscribe('onInputStatusChanged',({ data })=>{});
				// conversation
				const totalUnreadCountChangedHandler = ({data}) => {
					if (this.storeIsSyncing) {
						return;
					}
					this.$store.commit("conversation/SET_UNREAD_COUNT", data);
				};
				const newConversationHandler = ({data}) => {
					if (this.storeIsSyncing) {
						return;
					}
					const result = [...data, ...this.storeConversationList];
					this.$store.commit(
						"conversation/SET_CONVERSATION_LIST",
						conversationSort(result)
					);
				};
				const conversationChangedHandler = ({data}) => {
					//console.log('conversationChangedHandler',data);
					if (this.storeIsSyncing) {
						return;
					}
					let filterArr = [];
					//console.log(data);
					const chids = data.map((ch) => ch.conversationID);
					filterArr = this.storeConversationList.filter((tc) => !chids.includes(tc.conversationID));
					const idx = data.findIndex((c) =>c.conversationID === this.storeCurrentConversation.conversationID);
					if (idx !== -1){
						this.$store.commit("conversation/SET_CURRENT_CONVERSATION",data[idx]);
					}
					const result = [...data, ...filterArr];
					this.$store.commit("conversation/SET_CONVERSATION_LIST",conversationSort(result));
				};
				//会话总未读发生变化时的回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnTotalUnreadMessageCountChanged,totalUnreadCountChangedHandler);
				//有新会话产生时，会收到此回调。
				IMSDK.subscribe(IMSDK.IMEvents.OnNewConversation, newConversationHandler);
				//某些会话的关键信息发生变化时，会触发该回调，例如会话的未读数发生变化，会话的最后一条消息发生变化等。
				IMSDK.subscribe(IMSDK.IMEvents.OnConversationChanged,conversationChangedHandler);
		
			},
		
			async tryLogin() {
				const _this = this;
				const IMToken = uni.getStorageSync("IMToken");
				const IMUserID = uni.getStorageSync("IMUserID")+'';
				//console.log('IMToken:',IMToken);
				//console.log('IMUserID:',IMUserID);
				const path = await getDbDir();
				//console.log('path:',path);
				const IMConfig = {
					systemType: "uni-app",
					apiAddr: config.getApiUrl(), // SDK的API接口地址。如：http://xxx:10002
					wsAddr: config.getWsUrl(), // SDK的websocket地址。如： ws://xxx:10001
					dataDir: path, // 数据存储路径
					logLevel: 6,
					logFilePath: path,
					isLogStandardOutput: true,
					isExternalExtensions: false,
				};
				//console.log('IMConfig:',IMConfig);
				const flag = await IMSDK.asyncApi(IMMethods.InitSDK, IMSDK.uuid(), IMConfig);
				//console.log('flag:',flag);
				if (!flag) {
					plus.navigator.closeSplashscreen();
					console.log('初始化IMSDK失败！');
					uni.$u.toast("初始化IMSDK失败！");
					return;
				}
				
				_this.setGlobalIMlistener();
				// setTimeout(()=>{
					
				// },1000);
				let status;
				do{
					status = await IMSDK.asyncApi(IMSDK.IMMethods.GetLoginStatus,IMSDK.uuid());
					//console.log(status);
				}while(status == -1001);
				if (status === 3) {
					console.log('初始化,已经登录！');
					_this.initStore();
					return;
				}
				if (status === 1) {
					IMSDK.asyncApi(IMSDK.IMMethods.Login, IMSDK.uuid(), {
							userID: IMUserID,
							token: IMToken,
						})
						.then(_this.initStore)
						.catch((err) => {
							console.log(err);
							uni.removeStorage({
								key: "IMToken",
							});
							uni.removeStorage({
								key: "BusinessToken",
							});
							plus.navigator.closeSplashscreen();
						});
				}

			},
			
			handleOfflineNewMessages(newServerMsg) {
				console.log(newServerMsg);
				console.log( getConversationContent(newServerMsg));
				uni.createPushMessage({
					title:"您的朋友发来新的消息",
					content:getConversationContent(newServerMsg),
					payload:{
						type:"msg",
						data:newServerMsg
					},
					//icon:'',
					//sound:'',
					//cover:'false',
					//delay:0,
					//when:0,//消息上显示的提示时间
					//channelId:"",
					//category:"",
					success(res){
						//console.log(res);
					},
					fail(res){
						//console.log(res);
					},
					complete(res){
						//console.log(res);
					}
				});
			},
			
			handleNewMessage(newServerMsg) {
				if (this.inCurrentConversation(newServerMsg)) {
					if (
						newServerMsg.contentType !== MessageType.TypingMessage &&
						newServerMsg.contentType !== MessageType.RevokeMessage
					) {
						newServerMsg.isAppend = true;
						this.pushNewMessage(newServerMsg);
						setTimeout(() => uni.$emit(PageEvents.ScrollToBottom, true));
						uni.$u.debounce(this.markConversationAsRead, 2000);
					}
				}else{
					this.handleOfflineNewMessages(newServerMsg);
				}
			},
			
			inCurrentConversation(newServerMsg) {
				switch (newServerMsg.sessionType) {
					case SessionType.Single:
						return (
							newServerMsg.sendID === this.storeCurrentConversation.userID ||
							(newServerMsg.sendID === this.storeCurrentUserID &&
								newServerMsg.recvID === this.storeCurrentConversation.userID)
						);
					case SessionType.WorkingGroup:
						return newServerMsg.groupID === this.storeCurrentConversation.groupID;
					case SessionType.Notification:
						return newServerMsg.sendID === this.storeCurrentConversation.userID;
					default:
						return false;
				}
			},
			
			markConversationAsRead() {
				IMSDK.asyncApi(
					IMSDK.IMMethods.MarkConversationMessageAsRead,
					IMSDK.uuid(),
					this.storeCurrentConversation.conversationID
				);
			},
			
			initStore() {
				const _this = this;
				this.$store.dispatch("user/getSelfInfo");
				this.$store.dispatch("conversation/getConversationList");
				this.$store.dispatch("conversation/getUnReadCount");
				this.$store.dispatch("contact/getBlacklist");
				this.$store.dispatch("contact/getRecvFriendApplications");
				this.$store.dispatch("contact/getSentFriendApplications");
				this.$store.dispatch("contact/getRecvGroupApplications");
				this.$store.dispatch("contact/getSentGroupApplications");
				this.$store.dispatch("contact/getFriendList");
				this.$store.dispatch("circle/getFriendCircleInfo");
				
				if(true !== this.handleArguments()){
					uni.switchTab({
						url: "/pages/conversation/conversationList/index?isRedirect=true",
						complete() {
							_this.keppAlive();
							_this.checkUpdate();
						},
						fail(e){
							//console.log(e);
						}
					});
				}
			},
			
			// 验证是否升级
			checkUpdate() {
				const _this = this;
				checkUpgrade();
			},
			
			keppAlive(){
				// #ifdef APP-NVUE
				uni.requestPermissions(['android.permission.RECEIVE_BOOT_COMPLETED'], (result) => {
					if (result.granted) {
						console.log('权限已获得');
					} else {
						console.log('权限被拒绝');
						uni.showModal({
							title: '权限申请',
							content: '您需要授权后台运行权限才能正常使用该功能',
							showCancel: false
						});
					}
				});
				// #endif
			},
			
			handleArguments(){
				var args= plus.runtime.arguments;
				if(args){
					if(args.startsWith('shunliao://')){
						console.log(args);
						return ;
					}
					if(args.startsWith('{')){
						const json = JSON.parse(args);
						if(json.type == 'msg'){
							if(this.inCurrentConversation(json.data)){
							}else{
								let conversation = this.storeConversationList.find((item) => item === json.data);
								if(conversation){
									plus.navigator.closeSplashscreen();
									prepareConversationState(conversation);
									return true;
								}
							}
						}
						return ;
					}
					// 处理args参数，如直达到某新页面等
					console.log(args);
				}
			}
		}
	};
</script>

<style lang="scss">
	@import "@/static/imfont/iconfont.css";
	/*每个页面公共css */
	text,view{
		font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
	}
	@import "@/uni_modules/uview-ui/index.scss";
	@import "@/styles/login.scss";
	@import "@/styles/global.scss";

	uni-page-body {
		height: 100vh;
		overflow: hidden;
	}

	.uni-tabbar .uni-tabbar__icon {
		width: 28px !important;
		height: 28px !important;
	}
</style>