<template>
	<view class="box">
		<view class="content">
			<view>
				<label class="radio" @click="isWifi=true">
					<radio value="wifi" :checked="isWifi" />wifi
				</label>
				<label class="radio" @click="isWifi=false">
					<radio value="4G" :checked="!isWifi" />4G
				</label>
			</view>
			<view class="input-row">
				<text>wifi名称：</text>
				<input class="edittext" v-model="wifiName" />
			</view>
			<view class="input-row">
				<text>wifi密码：</text>
				<input class="edittext" v-model="wifiPwd" />
			</view>
			<view style="margin-top: 10rpx;">
				<button @click="connectBle()">下一步</button>
			</view>
			<text style="margin-top: 10rpx;">{{errorText}}</text>
		</view>

		<view class="loadView" v-if="showLoading">
			<image class="rotateAnim" src="../../static/loading.svg"></image>
			<text style="margin-left: 10rpx;">{{loadingText}}</text>
		</view>

	</view>
</template>

<script>
	const server_uuid = "0000FFE5-0000-1000-8000-00805F9B34FB";
	//const baidu_server_uuid = "00001111-0000-1000-8000-00805f9b34fb";
	export default {

		data() {
			return {
				deviceName: "",
				deviceId: "",
				isWifi: true,
				wifiName: "JackieHou_Mac",
				wifiPwd: "1234567890",
				connected: false,
				connecting: false,
				iccid: '',
				withoutWifiInterval: undefined,
				configTimeout: undefined,
				showLoading: false, //是否显示loading
				loadingText: '正在连接设备', //load框的文字提示
				errorText: "",

			}
		},
		onLoad(option) {
			this.deviceName = option.name;
			this.deviceId = option.mac
			console.log(`name = ${this.deviceName},mac = ${this.deviceId}`);
			//this.getWifiBuffer()
		},
		methods: {
			test2() {
				function doSomething(str) {
					return new Promise((resolve, reject) => {
						setTimeout(() => {
							resolve(str.toUpperCase());
						}, 2000)

					})
				}

				let strs = ['aaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeeeee'];
				let promiseList = strs.map(doSomething);
				let time = Date.now();
				(async () => {
					let res = await Promise.allSettled(promiseList)
					console.log(Date.now() - time);
					console.log(res);
				})();
			},
			test() {
				let buffer = Buffer.from(
					"1abcdefghijklmnopqrstuvwxyz2abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz")
				console.log(buffer.length);
				let count = Math.ceil(buffer.length / 20)
				let buffers = []
				for (var i = 0; i < count; i++) {
					let size = Math.min(20, buffer.length - i * 20)
					console.log(size);
					let buf = buffer.slice(i * 20, size + i * 20)
					buffers.push(buf)
				}
				for (let b of buffers) {
					console.log(b);
				}
			},
			connectBle() {
				let that = this
				if (!that.connecting && !that.connected) {
					console.log('创建连接')
					clearInterval(that.withoutWifiInterval)
					clearTimeout(that.configTimeout)
					that.connecting = true
					that.showLoading = true
					that.loadingText = '正在连接设备'
					that.errorText = ""
					uni.createBLEConnection({
						// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
						deviceId: that.deviceId,
						success(res) {
							that.connected = true
							console.log('连接成功')
							console.log(res)
							that.connecting = false
							that.loadingText = '正在获取服务'
							//获取服务
							that.getBleDeviceServices()
						},
						fail(err) {
							console.log('连接失败')
							console.log(err)
							that.connecting = false
							that.showLoading = false
							that.errorText = '连接失败！请将手机靠近设备'
							uni.showToast({
								title: '连接失败！请将手机靠近设备',
								icon: 'none',
								duration: 2000
							})
						}
					})
				}
			},
			listenBleConnectState() {
				uni.onBLEConnectionStateChange(function(res) {
					// 该方法回调中可以用于处理连接意外断开等异常情况
					console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
					that.connected = res.connected
					if (res.connected === false) {
						clearInterval(that.withoutWifiInterval)
						clearTimeout(that.configTimeout)
						that.showLoading = false
						that.errorText = '连接已断开，请重试！'
						uni.showToast({
							title: '连接已断开，请重试！',
							icon: 'none',
							duration: 2000
						})
					}
				})
			},
			getBleDeviceServices() {
				let that = this
				setTimeout(() => {
					uni.getBLEDeviceServices({
						deviceId: that.deviceId,
						success(res) {
							console.log('获取服务成功')
							console.log(res)
							for (let service of res.services) {
								console.log(service)
								if (server_uuid.toUpperCase() == service.uuid.toUpperCase()) {
									that.loadingText = '正在获取特征'
									//获取特征
									that.getBLEDeviceCharacteristics(server_uuid)
									return
								}
							}
						},
						fail(err) {
							console.log('获取服务失败')
							console.log(err);
							that.closeBLEConnection()
							that.errorText = '获取服务失败'
						}
					})
				}, 1000)

			},
			getBLEDeviceCharacteristics(uuid) {
				console.log("获取特征");
				let that = this
				//setTimeout(() => {
				uni.getBLEDeviceCharacteristics({
					deviceId: that.deviceId,
					serviceId: uuid,
					success(res) {
						console.log('获取特征成功');
						console.log(res);
						//todo直接写入数据
						//that.sendCongifComm(res.characteristics[0].uuid)
						that.notifyBLECharacteristicValueChange(res.characteristics[0].uuid)
					},
					fail(err) {
						console.log('获取特征失败');
						console.log(err);
						that.closeBLEConnection()
						that.errorText = '获取特征失败'
					}
				})
				//}, 1000)
			},
			notifyBLECharacteristicValueChange(characteristicId) {
				let that = this
				setTimeout(() => {
					that.loadingText = '正在配网'

					//设置一个超时配网的时间
					that.configTimeout = setTimeout(() => {
						that.closeBLEConnection()
						uni.showToast({
							title: "配网超时，请重试",
							icon: 'none',
							duration: 1000
						})
						that.errorText = '配网超时，请重试'
					}, 20 * 1000)

					uni.notifyBLECharacteristicValueChange({
						state: true,
						deviceId: that.deviceId,
						serviceId: server_uuid,
						characteristicId: characteristicId,
					}).then(res => {
						console.log("notify成功");
						console.log(res);
					}).catch(err => {
						console.log("notify失败");
						console.log(err);
					})

					//监听设备发送过来的数据
					uni.onBLECharacteristicValueChange(function(res) {
						//console.warn('收到设备发送过来的数据');
						//console.log(res);
						let buf = Buffer.from(res.value);
						let receiveStr = buf.toString()
						console.log(`收到数据：${receiveStr}`);
						if (receiveStr === 'connect_success') {
							let text = `${that.isWifi ? 'WIFI' : '4g'}配网成功`
							uni.showToast({
								title: text,
								icon: 'none',
								duration: 1000
							})
							that.closeBLEConnection()
							that.errorText = text
						} else if (receiveStr.indexOf('failure') >= 0) {
							uni.showToast({
								title: '配网失败',
								icon: 'none',
								duration: 1000
							})
							that.closeBLEConnection()
							that.errorText = '配网失败'
						} else if (receiveStr.indexOf('ic0:') >= 0) { //用来获取iccid的
							that.iccid = receiveStr.substring(4, receiveStr.length);
						} else if (receiveStr.indexOf('ic1:') >= 0) { //用来获取iccid的 把ic0 和ic1拼接起来
							let ic1 = receiveStr.substring(4, receiveStr.length);
							that.iccid = that.iccid + ic1;
							//发送4G配网指令
							//let buf = Buffer.from('without_WiFi')
							//setTimeout(() =>{that.sendCongifCmd(characteristicId,buf.buffer)},800)
							setTimeout(() => {
								that.sendWithoutWifiCommand(characteristicId);
							}, 800)
						} else if (receiveStr.indexOf('start_network') >= 0 || receiveStr.indexOf(
								'recv_finish') >= 0) {
							//发送	AIrSMArT_CLOSE指令	
							setTimeout(() => {
								let buf = Buffer.from('AIrSMArT_CLOSE')
								that.sendCongifCmd(characteristicId,buf.buffer)
							}, 2000)
						} else if (receiveStr.indexOf('without_WiFi_OK') >= 0) {
							let text = `4G配网成功`
							uni.showToast({
								title: text,
								icon: 'none',
								duration: 1000
							})
							that.errorText = text
							that.closeBLEConnection()
						}
					})

					//发送数据给设备
					setTimeout(() => {
						let buffer
						if (that.isWifi) {
							buffer = that.getWifiBuffer()
							//that.sendCongifCmd(characteristicId,buffer)
						} else {
							//4G设备先获取iccid
							let buf = Buffer.from('get_iccid')
							buffer = buf.buffer
						}
						that.sendCongifCmd(characteristicId, buffer)
					}, 800)
				}, 1000)
			},
			sendCongifCmd(characteristicId, buffer) { //发送配网指令
				let that = this

				let count = Math.ceil(buffer.byteLength / 20)
				//拆分成的ArrayBuffer数组，每个ArrayBuffer不超过20个字节
				let buffers = []
				for (var i = 0; i < count; i++) {
					let size = Math.min(20, buffer.byteLength - i * 20)
					let buf = buffer.slice(i * 20, size + i * 20)
					buffers.push(buf)
				}

				//返回的是一个promise对象
				function sendData(buffer) {
					return uni.writeBLECharacteristicValue({
						deviceId: that.deviceId,
						serviceId: server_uuid,
						characteristicId: characteristicId,
						value: buffer,
					})
				};

				(async () => {
					for (let b of buffers) {
						let res = await sendData(b)
						//console.log(res);
						console.log(`发送的数据为：${Buffer.from(b)} errorCode: ${res[res.length-1].errCode}`);
					}
					// let promises = buffers.map((b) => sendData(b))
					// let res  = await Promise.all(promises)
				})();
			},
			sendCongifCmd1(characteristicId, buffer) { //发送配网指令
				let that = this
				uni.writeBLECharacteristicValue({
					deviceId: that.deviceId,
					serviceId: server_uuid,
					characteristicId: characteristicId,
					value: buffer,
					success(res) {
						console.log(`发送数据成功 ${Buffer.from(buffer)}`);
						console.log(res)
					},
					fail(err) {
						console.log(`发送数据失败 ${Buffer.from(buffer)}`);
						console.log(err)
					}
				})
			},
			sendWithoutWifiCommand(characteristicId) { //间隔2S发送WithoutWifi指令，直到设备有返回指令
				let that = this

				function sendWithoutWifi(uuid) {
					let buf = Buffer.from('without_WiFi')
					that.sendCongifCmd(characteristicId, buf.buffer)
				}
				if (that.withoutWifiInterval === undefined) {
					that.withoutWifiInterval = setInterval(sendWithoutWifi, 2000, characteristicId)
				}
				sendWithoutWifi()
			},
			getWifiBuffer() {
				let ssidBuf = Buffer.from(this.wifiName)
				console.log(ssidBuf.length);

				let pwdBuf = Buffer.from(this.wifiPwd)
				console.log(pwdBuf.length);

				let buffer = new ArrayBuffer(ssidBuf.length + pwdBuf.length + 6);
				let dataView = new DataView(buffer);

				dataView.setUint8(0, 0x22)
				dataView.setUint8(1, ssidBuf.length + pwdBuf.length + 6)
				dataView.setUint8(2, 0x33)
				dataView.setUint8(3, ssidBuf.length)
				let j = 0
				for (var i = 4; i < ssidBuf.length + 4; ++i) {
					dataView.setUint8(i, ssidBuf[j++])
				}

				dataView.setUint8(ssidBuf.length + 4, 0x44)
				dataView.setUint8(ssidBuf.length + 5, pwdBuf.length)
				j = 0
				for (var i = ssidBuf.length + 6; i < ssidBuf.length + pwdBuf.length + 6; ++i) {
					dataView.setUint8(i, pwdBuf[j++])
				}
				//打印arrayBuffer
				// let buf = Buffer.from(buffer);
				// console.log(buf);

				//console.log(buffer.byteLength)
				return buffer;
			},
			closeBLEConnection() {
				let that = this
				uni.closeBLEConnection({
					deviceId: that.deviceId,
					success(res) {
						console.log('关闭连接成功');
						console.log(res)
					},
					fail(err) {
						console.log(err)
						console.log('关闭连接失败');
					}
				})
				clearInterval(that.withoutWifiInterval)
				clearTimeout(that.configTimeout)
				that.connected = false
				that.showLoading = false
			}

		}
	}
</script>

<style>
	.box {
		display: flex;
		flex-direction: column;
		width: 100vw;
		height: 100vh;
	}



	.content {
		display: flex;
		flex-direction: column;

		/* align-items: center;
	justify-content: center; */
	}

	.input-row {
		display: flex;
		margin-top: 10rpx;
		flex-direction: row;
		align-items: center;
	}

	.loadView {
		display: flex;
		flex-direction: column;
		align-self: center;
		align-items: center;
		/* margin-top: 35vh; */
	}

	.edittext {
		display: flex;
		width: 60vw;
		height: 50rpx;

		border: 1rpx solid #333333;
	}

	.rotateAnim {
		width: 60rpx;
		height: 60rpx;
		animation: turn 1200ms linear infinite;
	}

	@keyframes turn {
		0% {
			transform: rotate(0deg);
		}

		50% {
			transform: rotate(180deg);
		}

		100% {
			transform: rotate(360deg);
		}
	}
</style>
