<template>
	<view class="content">
		<canvas canvas-id="flashCanvas"
			style="width: 160px; height: 80px; z-index: 9999;position: fixed; top:-9999px;left:-9999px;"></canvas>

		<f-video ref="compARef" :src="videoPath" :direction="-90" :autoplay="true" @shotVideoClick="shotVideoClick"
			:videoWidth="videoWidth" :videoHeight="videoHeight"></f-video>

		<view>
			<text>并发包数量</text>
			<input type="text" v-model="packgeCnt" />
		</view>
		<view>
			<text>发送间隔</text>
			<input type="text" v-model="inteval" />
		</view>
		<view>
			<button @click="checkVideo">选择视频</button>
			<!-- <button @click="CutImg">发送</button> -->
			<button @click="uploadVideo">发送</button>
		</view>


		<view class="sending-progress" v-if="isSending">
			<view class="progress-bar">
				<view class="progress-fill" :style="{ width: progress + '%' }"></view>
			</view>
			<text>正在发送: {{ progress }}% ({{ currentPacket }}/{{ totalPackets }})</text>
		</view>

	</view>
</template>

<script>
	export default {
		data() {
			return {
				videoPath: '',
				packgeCnt: 20,
				inteval: 0,
				progress: 0,
				currentPacket: 0,
				totalPackets: 100,

				connectedDeviceId: '',
				serviceId: '0xFFE1',
				writeCharacteristicId: '0xFFE1',
				notifyCharacteristicId: '0xFFE2',
				isSending: "",
				textProgress: "",

				imgs: [],
				videoWidth: 320,
				videoHeight: 160,
				videoDuration: 2,

				hexArray: []

			}
		},
		onLoad() {
			const eventChannel = this.getOpenerEventChannel();

			eventChannel.on('receiveDevice', (data) => {
				this.connectedDeviceId = data.connectedDeviceId;
				this.serviceId = data.serviceId;
				this.writeCharacteristicId = data.writeCharacteristicId;
				this.notifyCharacteristicId = data.notifyCharacteristicId;
			})
		},
		methods: {
			checkVideo: function() {
				uni.chooseVideo({
					sourceType: ['album', 'camera'],
					compressed: false,
					maxDuration: 2,
					camera: 'back',
					success: (res) => {
						this.videoPath = res.tempFilePath;

						this.imgs = [];
						this.hexArray = [];
						this.$refs.compARef.base64 = [];
						this.videoWidth = res.width;
						this.videoHeight = res.height;
						this.videoDuration = res.duration;
						console.log("视频宽:" + res.width + ",视频高:" + res.height + ",视频时长:" + res.duration);
					}
				})
			},

			uploadVideo: function() {

				if (this.hexArray.length > 0) {
					console.log("开始处理,无需上传");
					this.shotVideoClick(this.hexArray, 'rgb565');
					return;

				}
				if(!this.videoPath){
					uni.showToast({
						title: "请选择视频",
						icon: 'fail'
					})
					return;
				}
				
				console.log("正在上传视频");
				uni.showLoading({
					title: "上传中"
				});
				
				let p2=new Promise((resolve,reject)=>{
					console.log("Common.baseURL="+Common.baseURL);
					let start = new Date();
					uni.uploadFile({
						url: Common.baseURL+'video/upload',
						// url: 'http://192.168.110.169:5000/video/upload',
						filePath: this.videoPath,
						name: 'file',
						header: {
							"Method": "POST",
							"Content-Type": "multipart/form-data"
						},
						timeout: 600000,
						fail: (ex) => {
							//console.log("上传视频失败" + JSON.stringify(ex));
							uni.showToast({
								title: "视频文件上传失败了,请检查网络连接",
								icon: 'fail'
							})
							uni.hideLoading();
							reject(ex);
						},
						success: (res) => {
							let end = new Date();
							var diff = (end.getTime() - start.getTime()) / 1000;
							let s = diff % 60;
							let m = (diff - s) / 60;
							console.log("上传完成,耗时:" + m + "分" + s + "秒");
							uni.hideLoading();
							resolve(res);
						}
					
					});
				});
				
				let p1=this.HoldYouHand();
				
				Promise.all([p2,p1]).then((arr)=>{
					if(arr[1]===true){
						let res=arr[0];
						res = JSON.parse(res.data);
											
						if (res.data) {
							this.hexArray = res.data;
							uni.showLoading({
								title: "正在发送"
							});
											
							setTimeout(() => {
								this.shotVideoClick(res.data, 'rgb565');
							}, 0)
											
						} else {
							console.log("res")
							uni.showModal({
								content: "服务器未返回RGB565数据",
								title: '错误'
							})
						}
					}else{
						uni.showModal({
							content:"与设备握手失败了",
							title:"错误"
						})
					}
					
				});

			},
			pause(e) {
				////console.log('pause--------------------------', e);
			},
			shotVideoClick: function(array, type) {
				//console.log("处理视频完成", array);
				//console.log("type=" + type)
				//console.log("array=", array);
				this.imgs = array;



				var sendImagePackets = (imageData) => {
					return new Promise((resolve, reject) => {

						this.isSending = true;
						this.progress = 0;
						this.currentPacket = 0;

						// 总数据包数
						const totalPackets = 1536;
						this.totalPackets = totalPackets;
						let currentPacket = 1;
						let promises = [];
						// 发送单个数据包
						const sendNextPacket = () => {
							////console.log("currentPacket="+currentPacket+",imageData.length="+imageData.length);
							if (currentPacket > totalPackets) {
								this.isSending = false;
								resolve();

								return;
							}

							// 计算当前包的数据
							let packetSize = 250;
							if (type == 'rgb565') {
								packetSize = 500;
							}

							// 创建数据包
							const startIndex = (currentPacket - 1) * packetSize;
							const endIndex = Math.min(startIndex + packetSize, imageData.length);
							if (startIndex > endIndex) {
								resolve();
								return;
							}
							////console.log("111111");
							const packetData = imageData.slice(startIndex, endIndex);

							// 构建数据包
							////console.log("packetData.length"+packetData.length);
							const bufferSize = 506; // 头部5字节 + 数据部分
							const buffer = new ArrayBuffer(bufferSize);
							const dataView = new DataView(buffer);

							let sortNo = currentPacket.toString(16).padStart(4, '0');

							// 填充头部
							dataView.setUint8(0, 0x55); // 帧头
							dataView.setUint8(1, 0x04); // 帧类型：开机画面
							dataView.setUint8(2, '0x' + sortNo.substring(0, 2)); // 包序号
							dataView.setUint8(3, '0x' + sortNo.substring(2, 4)); // 包序号


							dataView.setUint8(4, 0x01);
							dataView.setUint8(5, 0xF4);


							if (type == 'rgb565') {
								for (let i = 0; i < packetData.length; i++) {
									dataView.setUint8(6 + i, '0x' + packetData[i]);
								}
							} else {
								for (let i = 0; i < packetData.length; i++) {
									dataView.setUint16(6 + i * 2, packetData[i], false);
								}
							}


							let inteval = parseInt(this.inteval ? this.inteval : 0);
							let promise = this.sendData(buffer);
							promises.push(promise);
							let packgeCnt = parseInt(this.packgeCnt || 20);
							if (currentPacket % packgeCnt == 0 || (currentPacket >= totalPackets &&
									promises.length > 0)) {
								Promise.all(promises).then(() => {
									if (currentPacket >= totalPackets) {
										this.isSending = false;
										resolve();
										return;

									}

									this.currentPacket = currentPacket;
									this.progress = Math.round((currentPacket / totalPackets) *
										100);
									currentPacket++;
									setTimeout(sendNextPacket, inteval);
								})
							} else {
								currentPacket++;
								sendNextPacket();
							}
							// .then(() => {
							// 	// 更新进度
							// 	this.currentPacket = currentPacket;
							// 	this.progress = Math.round((currentPacket / totalPackets) *
							// 		100);

							// 	currentPacket++;


							// 	setTimeout(sendNextPacket, inteval);
							// }).catch(err => {

							// 	console.log(err.errMsg+",发送失败了,正在补偿：" + currentPacket);
							// 	setTimeout(sendNextPacket, inteval);

							// });
						};

						//
						

							sendNextPacket();

					});
				}


				if (type == 'rgb565') {
					let start = new Date();
					console.log("开始发送");
					sendImagePackets(array).then(() => {

						let end = new Date();

						var diff = (end.getTime() - start.getTime()) / 1000;
						let s = diff % 60;
						let m = (diff - s) / 60;
						console.log("发送完成,耗时:" + m + "分" + s + "秒");
						uni.showToast({
							title: "发送完成,耗时:" + m + "分" + s + "秒",
							icon: 'success',

						})
					}).catch((ex1) => {
						//console.log("出现了异常", ex1)
					}).finally(() => {
						uni.hideLoading();
					});

					return;
				}


			},
			HoldYouHand() {
				
				var promise=new Promise((resolve,reject)=>{
					try{
						let start=new Date();
						var str = "video transmit start"; //握手的协议字符串
						console.log("开始握手:"+str)
						
						// 1. 创建 ArrayBuffer 和 DataView
						const buffer = new ArrayBuffer(str.length);
						const dataView = new DataView(buffer);
						
						// 2. 将字符串转换为 ASCII 码并写入 DataView
						for (let i = 0; i < str.length; i++) {
							dataView.setUint8(i, str.charCodeAt(i));
						}
						//console.log("111111");
						this.sendData(buffer).then(() => {
							// 开始发送第一个包							
							setTimeout(()=>{
								
								let end = new Date();
								var diff = (end.getTime() - start.getTime()) / 1000;
								let s = diff % 60;
								let m = (diff - s) / 60;
								
								console.log("握手成功并完成2200ms等待,耗时"+m+"分"+s+"秒");
								
								resolve(true);							
							}, 2200);
						
						}).catch(err => {
							//console.log("握手没有成功");
							reject(err);
						});
					}catch(ex){
						reject(ex);
					}
					
					
				});
				
				return promise;

			},
			sendData(buffer) {
				let sendBuffer = () => {
					return new Promise((resolve, reject) => {

						var promise = new Promise((succ, err) => {
							uni.writeBLECharacteristicValue({
								deviceId: this.connectedDeviceId,
								serviceId: this.serviceId,
								characteristicId: this.writeCharacteristicId,
								value: buffer,
								writeType: plus.os.name == 'iOS' ? 'write' : 'writeNoResponse',
								success: () => {
									// console.log("发送数据成功");
									succ();
								},
								fail: (ex) => {
									if (ex.code == '10007') {
										// console.log("失败重试");
										setTimeout(() => {
											sendBuffer().then(succ).catch(err);
										}, this.inteval || 0)
										// succ()

									} else

									{
										// console.log("发送数据失败",ex);
										err(ex);
									}
								},
								complete: function() {
									//console.log("123456");
								}
							});
						});
						if (plus.os.name == 'iOS') {

							function timeout(ms) {
								return new Promise((_, err) => {
									setTimeout(() => {
										err({
											code: -1,
											errMsg: '超时了'
										})
									}, ms);
								});
							}

							Promise.race([promise, timeout(this.inteval ? this.inteval : 0)]).then(() => {
									// console.log("成功了");
									resolve();
								})
								.catch((ex) => {

									if (ex.code == -1) {
										// console.log("超时了")
										resolve();
									} else {
										reject(ex);
										// console.log("异常了", ex);
										//sendBuffer().then(resolve).catch(reject);
									}

								});
						} else {

							promise.then(() => {
								//console.log("then........")
								resolve();
							}).catch(() => {
								//console.log("catch.........")
								reject()
							});
						}
					});

				}

				return sendBuffer();
			},
			CutImg: function() {
				if (this.imgs.length == 30) {
					this.shotVideoClick(this.imgs, 'img');
					return;
				}
				//console.log("开始处理视频")
				uni.showLoading({
					title: '开始处理'
				});
				this.$refs.compARef.shotVideoClick(0);
			}
		}
	}
</script>

<style>
	.sending-progress {
		margin-top: 30rpx;
		width: 100%;
	}

	.progress-bar {
		height: 12rpx;
		background-color: #e0e0e0;
		border-radius: 6rpx;
		overflow: hidden;
	}

	.progress-fill {
		height: 100%;
		background-color: #409eff;
		transition: width 0.3s;
	}

	input {
		border: 2rpx solid #000000;
	}

	button {
		height: 100rpx;
		line-height: 100rpx;
		font-size: 28rpx;
		float: left;
	}

	.content {
		width: 100vw;
		height: 300px;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}
</style>