<template>
	<page-meta :page-font-size="fontValue+'px'" :root-font-size="fontValue+'px'"></page-meta>
	<view>
		<cu-custom :isBack='true' >
		   <template v-slot:content>
		     <text class="text-jiachu text-black">在线通话</text>
		   </template>
		 </cu-custom>
		 <view class="IncolumnC">
		 	<image class="AvatarImg" :src="friendAvatar" mode="scaleToFill"></image>
		 	<text v-if="friend.value" class="text-black text-lg"></text>
		 	<text class="text-black text-lg" style="margin-top: 10rpx;">{{friendName}}</text>
			<view class="InrowC" style="margin-top: 80rpx;">
		 		<text class="text-black text-lg">{{stateNote}}</text>
		 		<image style="width: 52rpx;height: 52rpx;margin-left: 6rpx;" src="/static/mine/loading2.gif" mode=""></image>
		 	</view>
			<view class="InrowC" style="margin-top: 300rpx;">
				<image v-if="!canClose" style="width:110rpx ;height: 110rpx;" src="/static/mine/icon_on.png" mode="scaleToFill" @click="acceptWebrtc"></image>
				<image v-if="canClose" style="width:110rpx ;height: 110rpx;" src="/static/mine/icon_off.png" mode="scaleToFill" @click="closeWebrtcBT"></image>
				<image v-if="speacker" style="margin-left: 50rpx;width:110rpx ;height: 110rpx;" src="/static/mine/ysq_on.png" mode="scaleToFill" @click="changeSpeack"></image>
				<image v-if="!speacker" style="margin-left: 50rpx;width:110rpx ;height: 110rpx;" src="/static/mine/ysq_off.png" mode="scaleToFill" @click="changeSpeack"></image>
			</view>
		 </view>
	</view>
</template>

<script setup lang="ts">
	import {onLoad,onReady,onShow,onUnload} from '@dcloudio/uni-app';
	import {ref,watch} from 'vue'
	// import * as ASCIIUtils from '@/uni_modules/wrs-js-modbusCRCHex/js_sdk/wrs-ASCIIUtils.js';
	// import * as HexUtils from '@/uni_modules/wrs-js-modbusCRCHex/js_sdk/wrs-HexUtils.js';
	import {
		UTSWebRTC
	} from "@/uni_modules/wrs-uts-webrtc";
	import {
		UTSVoip,
		UTSLocalNotification,
		UTSVoipMgr
	} from "@/uni_modules/wrs-uts-voip"
	
	import MessageUtils from "@/utils/MessageUtils";
	import CuCustom from '@/colorui/components/cu-custom.vue'
	import UserApi from "@/api/UserApi";
	import {useUserStore} from '@/store/userStore'
	import {useWsStore} from "@/store/WsStore";
	import {storeToRefs} from "pinia";
	import type Webrtc from '@/mode/Webrtc';
	import ChatType from "@/utils/ChatType";
	import {usePeerStore} from "@/store/peerStore";
	import SendCode from '@/utils/SendCode'
    import Auth from "@/api/Auth";
    const fontValue=ref(Auth.getfontSize());
	
	let webRTC = new UTSWebRTC();
	let candidateList=[];
	let friendAvatar='/static/logo512.png';
	let friendName='';
	let stateNote =ref("正在呼叫");
	let audioObj=null;
	const timeCall=ref(0);
	const timer=ref();
	
	const wsStore = useWsStore();
	const peerStore = usePeerStore();
	const friendId = ref("");
	const friend = ref("");
	
	const startTime = ref(0)
	const isCaller = ref(false);
	const showVideo = ref(false);
	const speacker = ref(false);
	const canClose = ref(true);
	const user = useUserStore().getUser()
	const isConnect = ref(false)
	const videoIsOpen = ref(false)
	
	const hadClose = ref(false);

	
	
	const {isClose} = storeToRefs(peerStore)
	const {offer} = storeToRefs(peerStore)
	const {answer} = storeToRefs(peerStore)
	
	const {candidate} = storeToRefs(peerStore)
	const {isAccept} = storeToRefs(peerStore)
	
	
	watch(isAccept, (newVal) => {
	  if (newVal) {
		  timeCall.value=45;
	    getoffer();
	  }
	})
	watch(isClose, (newVal) => {
		console.log('isCloseisClose',newVal)
	  if (newVal) {
	    uni.navigateBack()
	  }
	})
	
	watch(offer, (newVal) => {
		console.log('offer',isCaller);
	  if (newVal) {//收到answeroffer
		  recOffer();
	  }
	})
	
	watch(answer, (newVal) => {
	  if (newVal) {//收到answer
		  recAnswer();
	  }
	})
	
	watch(candidate, (newVal) => {
	  if (newVal) {//收到candidate
	    console.log('candidate');
		var list = JSON.parse(newVal);
		list.forEach((item) => {
			webRTC.addIceCandidate({
				sdp: item.candidate,
				sdpMLineIndex: item.sdpMLineIndex,
				sdpMid: item.sdpMid
			}, (resp) => {
				console.log("addIceCandidate result:" + JSON.stringify(resp))
			})
		})
	  }
	  sendCandidate();
	})
	
	const chaoshipanduan = () => {
		timeCall.value=45;
		timer.value = setInterval(() => {
			timeCall.value=timeCall.value-1;
			if(timeCall.value==0&&!isConnect.value){
				MessageUtils.message('暂时无法连接，请稍后重试！')
			}
			else if(isConnect.value){
				clearInterval(timer.value);//正常接通
				return;
			}
			else if(timeCall.value<-2&&!isConnect.value){
				uni.navigateBack();
			}
		}, 1000);
	}
	
	const audioObjstart = () => {
		audioObj=uni.createInnerAudioContext();
		audioObj.loop=true;
		audioObj.volume=0.2;
		audioObj.src='/hybrid/html/images/calling.mp3';
		audioObj.play();
		
		setTimeout(function() {
		  // 这里写要延时执行的代码
		  if(showVideo.value){
		    console.log('onReady1');
		    webRTC.setSpeakerEnable(true)
			speacker.value=true;
		  }
		  else{
		    console.log('onReady2');
		    webRTC.setSpeakerEnable(false)
		  }
		}, 300); 
	}
	
	const audioObjstop = () => {
		if(audioObj){
			audioObj.stop();
		}
	}
	
	onShow(()=>{
		// console.log('onShow',videoIsOpen.value)
		if(videoIsOpen.value){
			//closeWebrtc();
			uni.navigateBack();
			return;
		}
		let state = UTSVoipMgr.getApplicationState()
		// console.log('getApplicationstate2-------',state);
		if(state!=2){
			if(uni.getSystemInfoSync().platform == "ios"&&!isCaller.value){
				//let provider = new UTSCXProvider()
				UTSVoipMgr.endCall({
					uuid: uni.getStorageSync("voip_UUID")
				}, (resp: any)=>{
					console.log(JSON.stringify(resp))
				})
			}
			initData();
			getfriendMsg();
			audioObjstart();
			setTimeout(function() {
			  // 这里写要延时执行
			  if(isCaller.value){//主动发起通话
			  }
			  else{
			  	acceptWebrtc();//自动接听
			  }
			}, 1500);
		}
	})
	onReady(()=>{
		console.log('onReady');
		chaoshipanduan();
	});
	onLoad((opt) => {
		console.log('onLoad')
		usePeerStore().updateBusyStatus(true)
		usePeerStore().updateCloseStatus(false)
		if(typeof opt?.isCaller === 'string'){
		  isCaller.value = opt?.isCaller === 'true'
		  if(isCaller.value){
			  canClose.value = true;
		  }
		  console.log('isCaller',canClose);
		}
		if(typeof opt?.showVideo === 'string'){
		  showVideo.value = opt?.showVideo === 'true'
		}
		candidateList=[];
		friendId.value = opt?.friendId;
	});
	
	const initData = () =>{
		webRTC.onCallback((resp) => {
			let opt = resp.opt
			//console.log(opt);
			switch (opt) {
				case "didChangeIceConnectionState": {
					let state = resp.state
					console.log(state);
					if(state==4||state==5||state==6){
						stateNote.value ='连接已断开';
					}
					if(state==2){
						console.log('已连接')
						audioObjstop();
						isConnect.value = true
						startTime.value = new Date().getTime()
						stateNote.value ='已连接';
						if(showVideo.value&&!videoIsOpen.value){//打开视频
						    videoIsOpen.value=true;
							webRTC.setSpeakerEnable(true)
							// uni.navigateTo({
							// 	url:'/imcall/iOSVideoView'
							// })
						}
					}
					// 0:RTCIceConnectionStateNew,
					// 1: RTCIceConnectionStateChecking,
					// 2:RTCIceConnectionStateConnected,
					// 3:RTCIceConnectionStateCompleted,
					// 4:RTCIceConnectionStateFailed,
					// 5:RTCIceConnectionStateDisconnected,
					// 6:RTCIceConnectionStateClosed,
					// 7: RTCIceConnectionStateCount,
				}
		
				break;
				case "didChangeIceGatheringState": {
					let state = resp.state
					// 0: RTCIceGatheringStateNew 
					// 1: RTCIceGatheringStateGathering 
					// 2: RTCIceGatheringStateComplete
				}
				break;
				case "didChangeSignalingState": {
					let state = resp.state
					// 0: RTCSignalingStateStable,
					//  1:RTCSignalingStateHaveLocalOffer,
					//  2:RTCSignalingStateHaveLocalPrAnswer,
					//  3:RTCSignalingStateHaveRemoteOffer,
					//  4:RTCSignalingStateHaveRemotePrAnswer,
					//  5: RTCSignalingStateClosed,
				}
				break;
				// 收集本机生成的Candidate
				case "didGenerateCandidate":
					//this.localCandidate = true
					let candidate = resp.candidate
					//console.log('iosCandidate',candidate)
					let data = {
						candidate: candidate.sdp,
						sdpMLineIndex: candidate.sdpMLineIndex,
						sdpMid: candidate.sdpMid,
					}
					candidateList.push(data);
					break;
				default:
					break;
			}
		})
		
		let params = {
			iceServers:[],
			sdpSemantics:1,
			continualGatheringPolicy:1,
			constraints:{}
		}
		// iceServer目前支持2种格式，更多格式请联系作者
		// 1.
		// {
		// 	urls: ["xxx"]
		// }
		//  2.
		// {
		// 	urls: ["xxx"],
		// 	username: "xxx",
		// 	credential: "xx"
		// }
		
		params.iceServers = [{
				urls: ["stun:203.175.169.52:3478",
					"turn:203.175.169.52:3478"
				],
				username: 'aaaaa',
				credential: 'bbbbb'
			}
		]
		params.sdpSemantics = 1 // 0: RTCSdpSemanticsPlanB 1:RTCSdpSemanticsUnifiedPlan
		params.continualGatheringPolicy =
			1 // 0: RTCContinualGatheringPolicyGatherOnce 1: RTCContinualGatheringPolicyGatherContinually
		params.constraints = {
			mandatory: {},
			optional: {
				DtlsSrtpKeyAgreement: "true"
			}
		}
		console.log(params);
		let suc = webRTC.peerConnection(params)
		console.log(suc);
		if (suc) {
			// 添加音频
			webRTC.addAudioTrack({
				trackId: "audio0",
				streamIds: ["stream"]
			})
			// 添加视频
			webRTC.addVideoTrack({
				trackId: "video0",
				streamIds: ["stream"]
			})
			// 添加数据channel
			webRTC.createDataChannel({
				label: "WebRTCData"
			})
			// 配置音频
			webRTC.configureAudioSession({
				category: "playAndRecord",
				mode: "voiceChat"
			})
		} else {
			console.log("peerConnection fail")
		}
	};
	
	const getfriendMsg = () => {
		UserApi.getUser(friendId.value).then((res) => {
		  friend.value = res.data
		  if (friend.value) {
		    friendName=friend.value.name;
			friendAvatar=encodeURI(friend.value.avatar);
			if(isCaller.value){//主动发起通话
				sendcallingMsg();
			}
			else{
				//acceptWebrtc();//自动接听
			}
		  }
		})
	}
	
	const changeSpeack = () => {
		if(speacker.value){
			speacker.value=false;
		}
		else{
			speacker.value=true;
		}
		console.log('setAudioEnabled',speacker.value)
		webRTC.setSpeakerEnable(speacker.value)
	}
	
	const acceptWebrtc = () => {
		console.log('acceptWebrtc');
		startTime.value = new Date().getTime()
		//给自己发一份忙碌状态，多个客户端同一个人不能同时接受，需要客户端接受后，其他客户端就关闭
		let data={
		    code: SendCode.WEBRTC_BUSY,
		    message: {
				chatId:friendId.value,
				fromId: user.id,
				type: ChatType.FRIEND,
				msgtype:'accept',
				video: showVideo.value,
		    }
		}
		console.log(data);
		useWsStore().send(JSON.stringify(data));
		canClose.value = true;
	}
	const closeWebrtcBT = () => {
		uni.navigateBack();
	}
	const closeWebrtc = () => {
		if (user.id) {
		  const closeMessage = {
		    code: SendCode.WEBRTC_CLOSE,
		    message: {
		      chatId:friendId.value,
		      fromId: user.id,
		      timestamp: new Date().getTime(),
		      type: ChatType.FRIEND,
		      msgtype:'close'
		    }
		  }
		  wsStore.send(JSON.stringify(closeMessage))
		  hadClose.value=true;
		  console.log('发送关闭消息', closeMessage)
		  //发起方才有发送视频结果消息的权限
		  if (isCaller.value) {
		    //界面展示视频消息情况，例如：对方是否接受了视频通话，通话时长
		    const message= {
				id:null,
				localtime:null,
				mine:true,
		        messageType:SendCode.WEBRTC_result,
		        chatId:friendId.value,
		        fromId: user.id,
		        timestamp: new Date().getTime(),
		        type: ChatType.FRIEND,
		        result: isConnect.value,
		        video: showVideo.value,
		        duration: isConnect.value ? new Date().getTime() - startTime.value : 0
		    }
		    console.log(message)
		    wsStore.sendWEBRTCresult(message);
		  }
		}
	}
	const sendSocketData = (data:any) => {
		wsStore.sendWEBRTC(data)
		console.log('发送消息', data);
	}
	
	const sendCandidate = () =>{
		let msg: Webrtc = {
		  chatId: friendId.value,
		  fromId: user.id,
		  type: ChatType.FRIEND,
		  msgtype:'candidate',
		  conetType:showVideo.value,
		  payload:JSON.stringify(candidateList)
		}
		console.log("将本机candidate发送给对方")
		sendSocketData(msg);
	}
	
	//主动发起通话操作，isCaller为true-----------------------------
	const sendcallingMsg = () => {
		console.log('sendcallingMsg');
		let msg: Webrtc = {
		  chatId:friendId.value,
		  fromId: user.id,
		  type: ChatType.FRIEND,
		  msgtype:'calling',
		  conetType:showVideo.value,
		  timestamp: new Date().getTime(),
		  payload:''
		}
		let data={
			code:SendCode.WEBRTC_CALL,
			message: msg
		}
		console.log('sendcallingMsg',data);
		useWsStore().send(JSON.stringify(data))
	}
	const getoffer = () => {
		var videoV="false";
		if(showVideo.value){
			videoV="true";
		}
		webRTC.offer({
			OfferToReceiveAudio: "true",
			OfferToReceiveVideo:videoV
		}, (resp:any) => {
			let flag = resp.flag
			if (flag) {
				let sdp = resp.sdp
				console.log("发送offer sdp",resp)
				let type = ""
				switch (sdp.type) {
					case 0:
						type = "offer"
						break;
					case 1:
						type = "prAnswer"
						break;
					case 2:
						type = "answer"
						break;
					case 3:
						type = "rollback"
						break;
					default:
						break;
				}
				let data = {
					type: "SessionDescription",
					payload: {
						sdp: sdp.sdp,
						type: type
					}
				}
				let msg: Webrtc = {
				  chatId: friendId.value,
				  fromId: user.id,
				  type: ChatType.FRIEND,
				  msgtype:'offer',
				  conetType:showVideo.value,
				  payload:JSON.stringify(data.payload)
				}
				// 发送给接听方
				sendSocketData(msg)
			} else {
				console.log(resp)
			}
		})
	}
	onUnload(()=>{
		clearInterval(timer.value);//正常接通
		audioObjstop();
		if(!hadClose.value){
			closeWebrtc();
		}
		webRTC.close();
		peerStore.setCallId(undefined);
		peerStore.setOffer(undefined);
		peerStore.setAnswer(undefined);
		peerStore.setCandidate(undefined);
		peerStore.updateBusyStatus(false);
		peerStore.updateCloseStatus(false);
		peerStore.setIsAccept(false);
	});
	//收到answer
	const recAnswer = () => {
		let answer=JSON.parse(peerStore.offer)
		console.log('answeroffer',answer);
		webRTC.setRemoteDescription({
			type: 2,
			sdp:answer.sdp
		}, (resp:any) => {
			if(resp.flag){
				sendCandidate();
			}
			console.log("setRemoteDescription result:" + JSON.stringify(resp))
		})
	}
	
	//被动接听通话操作，isCaller为false-----------------------------
	//收到recOffer
	const recOffer = () => {
		
		let payload=JSON.parse(peerStore.offer)
		console.log('recOffer1',payload);
		// let payload2=JSON.parse(payload.payload)
		// console.log('recOffer2',payload2);
		webRTC.setRemoteDescription({
			type: 0,
			sdp: payload.sdp
		}, (resp:any) => {
			console.log("setRemoteDescription result:" + JSON.stringify(resp))
			cranswer();
		})
	}
	
	const cranswer = () => {
		var videoV="false";
		if(showVideo.value){
			videoV="true";
		}
		webRTC.answer({
			OfferToReceiveAudio: "true",
			OfferToReceiveVideo:videoV
		}, (resp) => {
			let flag = resp.flag
			if (flag) {
				let sdp = resp.sdp
				let type = ""
				switch (sdp.type) {
					case 0:
						type = "offer"
						break;
					case 1:
						type = "prAnswer"
						break;
					case 2:
						type = "answer"
						break;
					case 3:
						type = "rollback"
						break;
					default:
						break;
				}
				let data = {
					type: "SessionDescription",
					payload: {
						sdp: sdp.sdp,
						type: type
					}
				}
				// 发送给呼叫方
				let msg: Webrtc = {
				  chatId:friendId.value,
				  fromId:user.id,
				  type: ChatType.FRIEND,
				  msgtype:'answer',
				  conetType:showVideo.value,
				  payload:JSON.stringify(data.payload)
				}
				console.log('answer',msg)
				sendSocketData(msg)
			} else {
				console.log(resp)
			}
		})
	}
	
				
</script>

<style>
.AvatarImg{
	margin-top: 40rpx;
	width: 160rpx;
	height: 160rpx;
	border-radius: 10rpx;
}
.IncolumnC{
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content:center;
}
.InrowC{
	display: flex;
	flex-direction:row;
	align-items: center;
	justify-content:center;
}
</style>
