<template>
	<page-meta>
		<navigation-bar :title="$tt('navBar.connectResult')" title-align="center" background-color="#F1F3F9"
			front-color="#000000" />
	</page-meta>
	<view class="set-wifi">
		<view class="img-wrap">
			<u-loading-icon size="70"></u-loading-icon>
		</view>
		<view class="progress">
			<view>
				<text class="num">{{progress}}</text>
				<text class="unit">%</text>
			</view>
			<view class="dec">{{infoText}}</view>
			<view class="tip">{{$tt('bleConnect.sureMobileCloseDevAndNetworkUnobstructed')}}</view>
		</view>
		<view class="btn-wrap">
			<button class="back" @click="handleGoBack">{{$tt('bleConnect.goBack')}}</button>
			<button class="restart" @click="handleRelocation">{{$tt('bleConnect.reconfigNetwork')}}</button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				progress: 0,
				deviceId: '',
				ssid: '',
				pass: '',
				infoText: this.$tt('bleConnect.devRegistering'),
				interval: null, // 定时器
			};
		},
		onLoad(option) {
			const { deviceId, ssid, pass } = option;
			this.deviceId = deviceId;
			this.ssid = ssid;
			this.pass = pass;
		},
		mounted() {
			this.simulateLoading();
			this.connectBlueTooth(this.deviceId);
		},
		methods: {
			// 模拟进度条
			simulateLoading() {
				let currentProgress = 0;
				this.interval = setInterval(() => {
					currentProgress += 10;
					this.progress = currentProgress;
					if (currentProgress >= 100) {
						clearInterval(this.interval);
					}
				}, 1300); // 每500毫秒更新一次进度
			},
			// 连接蓝牙设备
			connectBlueTooth(deviceId) {
				this.infoText = this.$tt('bleConnect.devBeginsToConnect');
				this.closeBlueTooth(deviceId, () => {
					setTimeout(() => {
						uni.createBLEConnection({
							deviceId: deviceId,
							success: (res) => {
								this.infoText = this.$tt('bleConnect.devConnectSuccess');
								this.getBlueToothService(deviceId);
							},
							fail: (res) => {
								clearInterval(this.interval);
								this.infoText = this.$tt('bleConnect.devConnectFailed') +
									`：${res.errMsg}`;
							},
						});
					}, 2000);
				});
			},
			// 关闭蓝牙设备（手机端可以同时连接多个蓝牙设备，但是同一个蓝牙设备不能被多次连接，所以需要在每次连接前关闭BLE连接）
			closeBlueTooth(deviceId, callback) {
				uni.closeBLEConnection({
					deviceId: deviceId,
					success: (res) => {
						console.log('closeBLEConnection', res);
					},
					fail: (res) => {
						console.log('closeBLEConnection', res);
					},
					complete: callback,
				});
			},
			// 获取蓝牙设备服务uuid
			getBlueToothService(deviceId) {
				this.infoText = this.$tt('bleConnect.discoveryService');
				setTimeout(() => {
					uni.getBLEDeviceServices({
						deviceId: deviceId,
						success: (res) => {
							const services = res.services;
							if (services.length <= 0) {
								this.infoText = this.$tt('bleConnect.mainServiceNoFound');
								return;
							}
							this.infoText = this.$tt('bleConnect.findServiceLists') +
								`：${services.length}`;
							for (let i = 0; i < services.length; i++) {
								if (services[i].isPrimary) {
									this.infoText = this.$tt('bleConnect.uuid') +
										`：${services[i].uuid}`;
									this.getBlueToothCharacteristics(deviceId, services[i].uuid);
								}
							}
						},
						fail: (res) => {
							clearInterval(this.interval);
							this.infoText = this.$tt('bleConnect.obtainServiceFailed') +
								`：${res.errMsg}`;
						},
					});
				}, 5000)
			},
			// 获取设备特征值
			getBlueToothCharacteristics(deviceId, uuid) {
				this.infoText = this.$tt('bleConnect.keyExchange');
				uni.getBLEDeviceCharacteristics({
					deviceId: deviceId,
					serviceId: uuid,
					success: (res) => {
						// 这里会获取到两个特征值，一个用来写，一个用来读
						const chars = res.characteristics;
						if (chars.length <= 0) {
							this.infoText = this.$tt('bleConnect.signatureCodeNoFound');
							return;
						}
						this.infoText = this.$tt('bleConnect.findFeatureCode') +
							`：${chars.length}`;
						if (chars.length >= 1) {
							chars.forEach((item) => {
								const prop = item.properties;
								if (prop.notify === true || prop.notify === true) {
									this.receiveData(deviceId, uuid, item.uuid);
								} else if (prop.write === true) {
									this.sendData(deviceId, uuid, item.uuid);
								}
							});
						}
					},
					fail: (res) => {
						clearInterval(this.interval);
						this.infoText = this.$tt('bleConnect.findFeatureCodeFailed') +
							`：${res.errMsg}`;
					}
				});
			},
			// 接受蓝牙设备发送过来的数据
			receiveData(deviceId, serviceId, charId) {
				const timeOut = setTimeout(() => {
					this.infoText = this.$tt('bleConnect.acceptDataTimeout');
					this.closeBlueTooth(this.deviceId);
				}, 13000);
				uni.notifyBLECharacteristicValueChange({
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: charId,
					state: true,
					success: (res) => {
						uni.onBLECharacteristicValueChange((data) => {
							const resHex = this.ab2hex(data.value);
							let result = this.hexCharCodeToStr(resHex)
							result = JSON.parse(result);
							if (result) {
								this.infoText = this.$tt('bleConnect.configurationSuccess');
							} else {
								this.infoText = this.$tt('bleConnect.configurationFailed');
							}
							this.progress = 100;
							clearInterval(this.interval);
							clearTimeout(timeOut);
						});
					},
					fail: (res) => {
						clearInterval(this.interval);
						this.infoText = this.$tt('bleConnect.receiveDataFailed') + `：${res.errMsg}`;
					}
				});
			},
			// 向蓝牙设备发送数据
			sendData(deviceId, serviceId, charId) {
				this.infoText = this.$tt('bleConnect.sendConfigurationData');
				const data = {
					ssid: this.ssid,
					password: this.pass
				};
				const buffer = this.toBuffer(data);
				setTimeout(() => {
					uni.writeBLECharacteristicValue({
						value: buffer,
						deviceId: deviceId,
						serviceId: serviceId,
						characteristicId: charId,
						success: (res) => {
							this.infoText = this.$tt('bleConnect.sendSuccess');
						},
						fail: (res) => {
							clearInterval(this.interval);
							this.infoText = this.$tt('bleConnect.sendFailed') + `：${res.errMsg}`;
						},
					});
				}, 1000);
			},
			toBuffer(data) {
				const dataStr = JSON.stringify(data);
				const buffer = new ArrayBuffer(dataStr.length);
				let bufView = new Uint8Array(buffer);
				for (var i = 0; i < dataStr.length; i++) {
					bufView[i] = dataStr.charCodeAt(i);
				}
				return buffer;
			},
			// ArrayBuffer转16进度字符串
			ab2hex(buffer) {
				const hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('')
			},
			// 将16进制的内容转成我们看得懂的字符串内容
			hexCharCodeToStr(hexCharCodeStr) {
				var trimedStr = hexCharCodeStr.trim();
				var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
				var len = rawStr.length;
				if (len % 2 !== 0) {
					return "";
				}
				var curCharCode;
				var resultStr = [];
				for (var i = 0; i < len; i = i + 2) {
					curCharCode = parseInt(rawStr.substr(i, 2), 16);
					resultStr.push(String.fromCharCode(curCharCode));
				}
				return resultStr.join("");
			},
			// 返回
			handleGoBack() {
				this.closeBlueTooth(this.deviceId);
				uni.switchTab({
					url: '/pages/tabBar/home/index'
				});
			},
			// 重新配网
			handleRelocation() {
				this.closeBlueTooth(this.deviceId);
				uni.reLaunch({
					url: `/pagesB/home/device/add/bleConnect/index`
				});
			}
		},
	}
</script>

<style lang="scss">
	page {
		height: 100%;
		background: $uni-bg-color-grey;
	}
</style>
<style lang="scss" scoped>
	.set-wifi {
		.img-wrap {
			padding: 160rpx 0;
			text-align: center;
		}

		.progress {
			text-align: center;
			padding: 0 20rpx;

			.num {
				font-size: 80rpx;
				line-height: 100rpx;
			}

			.unit {
				margin-left: 10rpx;
			}

			.dec {
				font-size: 28rpx;
				line-height: 48rpx;
				color: #7e7e7e;
			}

			.tip {
				margin-top: 20rpx;
				font-size: 32rpx;
				line-height: 52rpx;
			}
		}

		.btn-wrap {
			position: fixed;
			left: 80rpx;
			right: 80rpx;
			bottom: 160rpx;

			.restart {
				display: flex;
				justify-content: center;
				align-items: center;
				height: 98rpx;
				border-radius: 18rpx;
				color: #486FF2;
				background-color: #fff;
				font-weight: 400;
				font-size: 32rpx;
				letter-spacing: 0.6rpx;
				border: 2rpx solid #486FF2;
				margin-top: 36rpx;
			}

			.back {
				display: flex;
				justify-content: center;
				align-items: center;
				height: 98rpx;
				border-radius: 18rpx;
				color: #fff;
				background-color: #486FF2;
				font-weight: 400;
				font-size: 32rpx;
				letter-spacing: 0.6rpx;
			}
		}

	}
</style>