import { store } from "@/store"
import { getStorage } from "../storage"
import toast from "../toast"


const connectVoid = uni.createInnerAudioContext()
class Bluetooth {

	constructor() {
		this.isOpenBle = false
		this.deviceId = ""
		this.serviceId = ""
		this.writeId = ""
		this.notifyId = ""
		this.openBluetoothAdapter()
	}
	//初始化蓝牙模块，检查蓝牙是否已打开
	openBluetoothAdapter() {
		return new Promise((resolve, reject) => {
			uni.openBluetoothAdapter({
				success: res => {
					this.isOpenBle = true
					resolve(res)
				},
				fail: err => {
					reject('请打开蓝牙和定位功能')
				},
			})
		})
	}
	//搜索周边蓝牙设备
	startBluetoothDevicesDiscovery() {
		if (!this.isOpenBle) {
			toast('请打开蓝牙和定位功能')
			return
		}

		let self = this
		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.startBluetoothDevicesDiscovery({
					success: res => {
						resolve(res)
					},
					fail: res => {
						reject('搜索设备失败')
					}
				})
			}, 300)
		})
	}
	// 搜索附近连接上或没有连接上的设备
	getBluetoothDevices() {
		return new Promise((resolve, reject) => {
			uni.getBluetoothDevices({
				success(res) {
					resolve(res)
				},
				fail(error) {
					reject('搜索失败')
				}
			})
		})
	}
	//停止搜索周报蓝牙设备
	stopBluetoothDevicesDiscovery() {
		let self = this
		return new Promise((resolve, reject) => {
			uni.stopBluetoothDevicesDiscovery({
				success: e => {
					uni.hideLoading()
				},
				fail: e => {
					uni.hideLoading()
					toast('停止搜索失败，请重试')
				}
			})
		})
	}
	//连接设备
	createBLEConnection() {
		let deviceId = this.deviceId
		let self = this

		return new Promise((resolve, reject) => {
			uni.createBLEConnection({
				deviceId,
				success: (res) => {
					resolve(res)
				},
				fail: err => {
					reject(err)
				}
			})
		});
	}

	//获取蓝牙设备所有服务(service)
	getBLEDeviceServices() {
		let _serviceList = []
		let deviceId = this.deviceId
		let self = this

		return new Promise((resolve, reject) => {
			setTimeout(() => {
				uni.getBLEDeviceServices({
					deviceId,
					success: res => {
						for (let service of res.services) {
							if (service.isPrimary) {
								_serviceList.push(service)
							}
						}
						if (res.services.length <= 0) {
							showToast('成功获取服务，但没有可用服务')
						}

						resolve(_serviceList)
					},
					fail: err => {
						//设备已连接，但未能获取设备服务，也有可能连接处于断开状态
						toast('未获取蓝牙设备相关服务')
						reject(err)
					},
				})
			}, 2000)
		});
	}

	//获取蓝牙设备某个服务中所有特征值(characteristic)
	getBLEDeviceCharacteristics() {
		let deviceId = this.deviceId
		let serviceId = this.serviceId

		let self = this
		return new Promise((resolve, reject) => {
			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success: res => {
					for (let _obj of res.characteristics) {
						//获取notify
						if (_obj.properties.notify) {
							self.notifyId = _obj.uuid
							uni.setStorageSync('notifyId', self.notifyId)
						}
						//获取writeId
						if (_obj.properties.write) {
							self.writeId = _obj.uuid
							uni.setStorageSync('writeId', self.writeId)
						}
					}

					let result = {
						'notifyId': self.notifyId,
						'writeId': self.writeId
					}
					//成功获取到设备的服务特征值，可以测试设备功能了
					//self.showToast('已获取打印机服务，请测试打印功能')
					resolve(result)
				},
				fail: err => {
					//已连接设备，但未能获取设备服务
					toast('未能获取设备相关服务，请重试')
					reject(err)
				}
			})
		});
	}

	//断开蓝牙链接
	closeBLEConnection() {
		let deviceId = this.deviceId
		uni.closeBLEConnection({
			deviceId,
			success(res) {
				console.log('蓝牙连接已断开')
			}
		})
	}
	//启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值
	notifyBLECharacteristicValue() {
		let deviceId = this.deviceId
		let serviceId = this.serviceId
		let characteristicId = this.notifyId
		//特征值变化时，异步通知提示
		uni.notifyBLECharacteristicValueChange({
			state: true, // 启用 notify 功能
			deviceId,
			serviceId,
			characteristicId,
			success(res) {
				//监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification
				uni.onBLECharacteristicValueChange(function (res) {

				})
			},
			fail(res) {
				console.log('notifyBLECharacteristicValueChange failed:' + res.errMsg)

			}
		})
	}
	//向低功耗蓝牙设备特征值中写入二进制数据。注意：必须设备的特征值支持 write 才可以成功调用
	writeBLECharacteristicValue(buffer) {
		let deviceId = this.deviceId
		let serviceId = this.serviceId
		let characteristicId = this.writeId


		return new Promise((resolve, reject) => {
			uni.writeBLECharacteristicValue({
				deviceId,
				serviceId,
				characteristicId,
				value: buffer,
				success(res) {
					resolve(res)
				},
				fail(err) {
					reject(err)
				}
			})
		})
	}

	//关闭蓝牙连接，想要连接要重新启动
	closeBluetoothAdapter() {
		uni.closeBluetoothAdapter({
			success: res => {
				console.log('断开蓝牙')
			}
		})
	}

	//若APP在之前已有搜索过某个蓝牙设备，并成功建立连接，可直接传入之前搜索获取的 deviceId 直接尝试连接该设备，无需进行搜索操作。
	reconnect() {
		(async () => {
			try {
				let data = getStorage('commitBTDevCharact')
				this.deviceId = this.deviceId || data.deviceId //设备id
				this.serviceId = this.serviceId || data.serviceId //服务id
				this.notifyId = this.notifyId || data.uuid //
				this.writeId = this.writeId || data.uuid //写入二进制数据 特征值id
				//连接蓝牙设备
				await this.createBLEConnection()
				//获取蓝牙设备服务
				//await this.getBLEDeviceServices()

				uni.hideLoading()
				if (!this.serviceId || this.serviceId == '') {
					//this.showToast('打印服务已断开，请到开发设置重新搜索蓝牙设备')
					uni.jxConfirm({
						title: '打印机断开提示',
						content: '打印服务已断开，请到设置重新搜索蓝牙设备',
						confirmText: '去连接设备',
						cancelText: '关闭',
						success: () => {
							uni.navigateTo({ url: '/subPages/merchantChild/printerSetUp/printerSetUp' })
						}
					})
				} else if (!this.writeId || this.writeId == '') {
					//重新获取蓝牙设备服务特征值
					await this.getBLEDeviceCharacteristics();
					connectVoid.src = '/static/audio/connect_success.mp3'
					connectVoid.stop()
					connectVoid.play()
					store.commit('storeInfo/setIsConnectPrinter', true)
					toast('蓝牙设备连接成功')
				} else {
					connectVoid.src = '/static/audio/connect_success.mp3'
					connectVoid.stop()
					connectVoid.play()
					store.commit('storeInfo/setIsConnectPrinter', true)
					toast('蓝牙设备连接成功')
				}

			} catch (err) {
				uni.hideLoading()
			}

		})();
	}
}

export default Bluetooth
