<template>
	<view class="kk-printer">
		<view class="kk-printer-btn" @tap="handlePrintTap" style="color:#FFF;">
			{{isPrinting?printingText:defaultText}}
		</view>
		<view class="kk-shadow" :class="isShowSearch?'show':''" @tap="handleSearchClose">
			<view class="kk-modal" @tap.stop="doNothing">
				<view class="kk-search-device">
					<view class="kk-btn-wrap">
						<view class="kk-btn-item confirm-btn" @tap="sousuo" v-if="!isSearching">
							搜索设备
						</view>
						<view class="kk-btn-item confirm-btn" v-else>
							搜索中...
						</view>
						<view class="kk-btn-item" @tap="stopSearchBtnTap">
							停止搜索
						</view>
					</view>
					<view class="kk-devices-wrap">
						<view class="empty-wrap" v-if="devicesList.length <= 0">
							<view class="empty-icon"></view>
							<view class="empty-text">无可搜索到的设备</view>
						</view>
						<view class="" v-else>
							<view class="kk-devices-item" v-for="(item,index) in devicesList" :key="index"
								@tap="lianejieshebei(item.deviceId)">
								<view class="name" style="color:#000;display: flex;flex-direction: column;">
									<text>设备名称：</text>
									<text>{{item.name?item.name:'未命名'}}</text>
								</view>
								<!-- <view class="rssi">
									<text>信号强度：</text>
									<text>({{item.RSSI}})</text>
								</view> -->
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import gbk from '@/components/kk-printer/utils/printUtil-GBK.js';
	import * as blesdk from './utils/bluetoolth';
	import util from './utils/util.js';
	export default {
		data() {
			return {
				//是否正在打印
				isPrinting: false,
				//是否正在搜索设备
				isSearching: false,
				//是否显示蓝牙列表
				isShowSearch: false,
				//按蓝牙名过滤
				filterName: '',
				//按信号过滤
				filterRSSI: -95,
				//设备列表
				devicesList: [],
				//打印图片断开连接等待时间
				picWaitTime:0,
				//连接的设备ID
				deviceId: '',
				//根据设备ID获取的服务
				services: '',
				//获取特征值时返回的三要素
				serviceId: '',
				writeId: '',
				readId: '',
				iosNo: false,
				deviceType: 'ios'
			}
		},
		props: {
			//按钮默认文字
			defaultText: {
				type: String,
				default: '打印'
			},
			//按钮打印中的文字
			printingText: {
				type: String,
				default: '打印中...'
			},
			bufferData: {
				type: Array,
				require: true
			},
			roomcode: {
				type: String,
				require: true
			},
			CustName: {
				type: String,
				require: true
			},
			roomid: {
				type: String,
				require: true
			}
		},
		mounted() {

		},
		onLoad() {

		},
		beforeDestroy() {

			this.stopSearchBtnTap();
		},
		methods: {
			doNothing() {
				return;
			},
			//点击打印按钮
			handlePrintTap() {
				let that = this
				uni.showLoading({
					mask: true,
					title: '打印中...'
				});
				uni.getSystemInfo({
					success(res) {
						that.deviceType = res.osName
					},fail(err){
						
					}
				})
				// 初始化蓝牙模块
				wx.openBluetoothAdapter({ //111
					mode: 'central',
					success: (res2) => {
						that.sousuo()
					},
					fail: (res) => {
						
						if (res.errCode == '10001') {
							uni.showToast({
								duration: 2000,
								title: "请打开蓝牙后，再进行连接",
								icon: 'none',
								mask: true
							})
						} else {
							that.tui.toast('连接失败，请重启蓝牙或删除小程序重新进入-1')
							that.isShowSearch = true
						}
						setTimeout(res => {
							uni.hideLoading();
						}, 2000)
					}
				})
			},
			// 开始搜索附近的蓝牙外围设备
			sousuo() {
				let that = this;
				this.devicesList = []
				wx.startBluetoothDevicesDiscovery({ //222
					success(res3) {
						
						that.jiantingshebei()
					},
					fail(err) {
						that.tui.toast('连接失败，请重启蓝牙或删除小程序重新进入-2',err)
						
						wx.closeBLEConnection({
							deviceId: uni.getStorageSync('deviceId'),
							success(res2) {
						
							},fail(err1){
								
							}
						})
						wx.closeBluetoothAdapter({
							success(res) {
								
							},fail(err2){
								
							}
						})
						uni.removeStorageSync('deviceId')
						that.handlePrintTap()
						that.isShowSearch = true
						setTimeout(res => {
							uni.hideLoading();
						}, 2000)
					}
				})
			},
			//停止搜索蓝牙设备
			stopSearchBtnTap() {
				wx.stopBluetoothDevicesDiscovery()
			},
			/**
			 * jiantingshebei方法，判断缓存中有没有deviceId等数据的时候，
			 * 有：	直接拿到缓存中的deviceId等，直接请求 wx.createBLEConnection 
			 * 没有：才会调用 wx.onBluetoothDeviceFound 搜索
			 */
			jiantingshebei() {
				let that = this;
				if (uni.getStorageSync('deviceId')) {
					// that.huoqufuwu(uni.getStorageSync('deviceId'))
					
					that.lianejieshebei(uni.getStorageSync('deviceId'))
				} else {
					uni.hideLoading();
					that.isShowSearch = true
					// 监听扫描到新设备事件
					wx.onBluetoothDeviceFound((res4) => { //333
						res4.devices.forEach((device) => {
							if (!device.name && !device.localName) {
								return
							}
							that.devicesList.push(device)
						})
					})
				}

			},
			lianejieshebei(deviceId) {
				let that = this;
				uni.showLoading({
					mask: true,
					title: '加载中...'
				});
				let timerId = setTimeout(() => {
					wx.closeBLEConnection({
						deviceId: deviceId,
						success(res2) {
					
						},fail(err1){
							
						}
					})
					wx.closeBluetoothAdapter({
						success(res) {
							
						},fail(err2){
							
						}
					})
					uni.removeStorageSync('deviceId')
					that.handlePrintTap()
					that.isShowSearch = true
					return
				}, 5000);
				
				// 连接设备
				wx.createBLEConnection({ //555
					deviceId: deviceId, // 搜索到设备的 deviceId
					success: () => {
						// 连接成功就清除定时器
						clearTimeout(timerId);
						that.isShowSearch = false
						that.huoqufuwu(deviceId)
					},
					fail: (res) => {
						
						clearTimeout(timerId);
						if(res.errno == '1509007'){
							that.huoqufuwu(deviceId)
						}
						if(res.errno == '1509003'){
							that.lianejieshebei(deviceId)
						}
					}
				})
			},
			huoqufuwu(deviceId) {
				let that = this;
				//获取服务
				wx.getBLEDeviceServices({ //666
					deviceId: deviceId, // 搜索到设备的 deviceId
					success: (res5) => {
						that.duxietezhengzhi(deviceId, res5)
					},
					fail: (res) => {
						that.tui.toast('连接失败，请重启蓝牙或删除小程序重新进入-4',res)
						
						wx.closeBLEConnection({
							deviceId: uni.getStorageSync('deviceId'),
							success(res1) {

							}
						})
						uni.removeStorageSync('deviceId')
						that.sousuo()
						that.isShowSearch = true
						setTimeout(res => {
							uni.hideLoading();
						}, 2000)
					}
				})
			},
			duxietezhengzhi(deviceId, res5) {
				let that = this;
				//读写特征值
				wx.getBLEDeviceCharacteristics({ //777
					deviceId: deviceId, // 搜索到设备的 deviceId
					serviceId: res5.services[0].uuid, // 上一步中找到的某个服务
					success: (res6) => {
						
						for (let i = 0; i < res6.characteristics.length; i++) {
							let item = res6.characteristics[i]
							that.startNoticeBle(deviceId, res5.services[0].uuid, res6.characteristics[2].uuid)
							if (item.properties.write) { // 该特征值可写

								uni.setStorageSync('deviceId', deviceId);
								uni.setStorageSync('serviceId', res5.services[0].uuid);
								uni.setStorageSync('characteristicId', item.uuid);
								that.xierushuju()
								return;
							}
						}
					},
					fail: (res) => {
						that.tui.toast('连接失败，请重启蓝牙或删除小程序重新进入-5',res)
						
						wx.closeBLEConnection({
							deviceId: uni.getStorageSync('deviceId'),
							success(res) {

							}
						})
						uni.removeStorageSync('deviceId')
						that.sousuo()
						that.isShowSearch = true
						setTimeout(res => {
							uni.hideLoading();
						}, 2000)
					}
				})
			},
			// 开启蓝牙数据监听
			startNoticeBle(deviceId, serviceId, characteristicId) {
				let _this = this
				uni.notifyBLECharacteristicValueChange({
					state: true, // 启用 notify 功能
					deviceId: deviceId,
					serviceId: serviceId,
					characteristicId: characteristicId,
					success(res) {
						
						_this.GetDataFromBle();
					},
					fail: function(err) {
						
					}
				})
			},
			// 设备返回的数据接收
			GetDataFromBle() {
				var _this = this;
				uni.onBLECharacteristicValueChange((res) => {
					// 此时可以拿到蓝牙设备返回来的数据是一个ArrayBuffer类型数据，所以需要通过一个方法转换成字符串
						
					_this.bleData = _this.ab2hex(res.value)
					console.log('返回值是什么',_this.bleData)
					uni.hideLoading()
					setTimeout(res=>{
						uni.closeBLEConnection({
							deviceId: uni.getStorageSync('deviceId'),
							success(res) {
								
								
							},
							fail(err) {}
						})
					},_this.picWaitTime)
					
				})
			},
			ab2hex(buffer) {
				const hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16)).slice(-2)
					}
				)
				return hexArr.join('')
			},
			xierushuju() {
				let that = this;
				//写入数据
				if (this.defaultText == '打印小票') {
					that.$emit('onPrintSmall');
				} else if (this.defaultText == '确认打印') {
					that.$emit('goPrint');
				} else if (this.defaultText == '小标签') {
					that.$emit('onPrintSmall1');
				}else {
					that.$emit('onPrint');
				}

				that.$nextTick(() => {
					var dataStr = ''
					for (let m = 0; m < that.bufferData.length; m++) {
						dataStr += that.bufferData[m]
					}
					const maxChunk = that.deviceType == 'android' ? 20 : 180;
					const delay = that.deviceType == 'android' ? 20 : 180; 

					let buffer = gbk.strToGBKByte(dataStr)
					if(dataStr.indexOf('EG ') != -1){
						that.picWaitTime = buffer.byteLength + 200
					}
					for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
						let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
						setTimeout(that._writeBLECharacteristicValue, j * delay, subPackage);
					}

				})
				return;
			},
			_writeBLECharacteristicValue(buffer) {
				let that = this;
				wx.writeBLECharacteristicValue({ 
					deviceId: uni.getStorageSync('deviceId'),
					serviceId: uni.getStorageSync('serviceId'),
					characteristicId: uni.getStorageSync('characteristicId'),
					value: buffer,
					success(res) {

					},
					fail(res) {
						wx.closeBLEConnection({
							deviceId: uni.getStorageSync('deviceId'),
							success(res) {

							}
						})
						if (uni.getStorageSync('deviceId')) {
							// that.xierushuju()
						} else {
							that.jiantingshebei()
						}
						uni.hideLoading();
					}
				})

			},
			handleSearchClose() {
				wx.closeBluetoothAdapter({
					success(res) {
						
					}
				})
				this.isShowSearch = false
			}
		}
	}
</script>

<style lang="scss" scoped>
	.kk-printer {
		&-btn {
			width: 100%;
			height: 100%;
		}

		.kk-shadow {
			display: none;
			z-index: 999;
			
			&.show {
				display: block;
				width: 100vw;
				height: 100vh;
				background: rgba(0, 0, 0, 0.4);
				position: fixed;
				top: 0;
				left: 0;
				display: flex;
				justify-content: center;
				align-items: center;

				.kk-modal {
					width: 420rpx;
					height: 600rpx;
					padding: 24rpx;
					box-sizing: border-box;
					overflow-y: auto;
					border-radius: 20rpx;
					background: #ffffff;
					display: flex;
					justify-content: center;
					align-items: center;

					.kk-search-device {
						width: 100%;
						height: 100%;

						.kk-filter-wrap {
							width: 100%;
							height: 160rpx;
							display: flex;
							flex-direction: column;
							justify-content: flex-start;
							align-items: flex-start;

							&>slider {
								width: 90%;
								height: 90rpx;
							}

							&>input {
								padding: 0 20rpx;
								box-sizing: border-box;
								border-radius: 10rpx;
								height: 90rpx;
								width: 100%;
								border: 1rpx solid #ebebeb;
							}
						}

						.kk-btn-wrap {
							width: 100%;
							height: 90rpx;
							display: flex;
							justify-content: space-between;
							align-items: center;
							padding: 20rpx;

							&>view {
								flex: 1 1 auto;
								height: 60rpx;
								line-height: 60rpx;
								border-radius: 16rpx;
								text-align: center;
								color: #ffffff;
								font-size: 26rpx;

								&.confirm-btn {
									background: #007AFF;
									margin-right: 30rpx;
								}

								&:nth-last-child(1) {
									background: #DD524D;
								}
							}
						}

						.kk-devices-wrap {
							height: calc(100% - 80rpx);
							overflow-y: auto;
							padding: 10rpx 20rpx;
							box-sizing: border-box;
							border: 1rpx solid #ebebeb;
							box-sizing: border-box;
							border-radius: 20rpx;

							.empty-wrap {
								width: 100%;
								height: 100%;
								display: flex;
								flex-direction: column;
								justify-content: center;
								align-items: center;

								.empty-icon {
									width: 268rpx;
									height: 240rpx;
									background-size: 100% 100%;
									margin-bottom: 26rpx;
								}

								.empty-text {
									width: 100%;
									line-height: 50rpx;
									font-size: 30rpx;
									text-align: center;
									color: #999999;
								}
							}

							.kk-devices-item {
								width: 100%;
								border-bottom: 1rpx solid #ebebeb;
								padding: 10rpx 0;
								box-sizing: border-box;
								z-index: 500;

								&:nth-last-child(1) {
									border-bottom: none;
								}

								&>view {
									width: 100%;
									font-size: 30rpx;
								}
							}
						}
					}
				}
			}

		}
	}
</style>