// import './encoding.js'; // 如需要 中文乱码问题 new TextEncoder
const printInteraction = {
    device_id: null,// 打印设备id
    service_id: '',
    write_id: '',
    notify_id: '',
    connFlag: false,
    services: [],
    stringData: [],
    callback: function () {},
    ab2hex: (buffer) => {//ArrayBuffer转16进度字符串示例
        const hexArr = Array.prototype.map.call(
            new Uint8Array(buffer),
            function (bit) {
                return ('00' + bit.toString(16)).slice(-2)
            }
        )
        return hexArr.join('')
    },
    // 获取蓝牙状态是否开启 准备
    getBluetooth: (callback) => {
        const _this = printInteraction;
        uni.getBluetoothAdapterState({
            success(res) {
                if (res.available) { // 蓝牙适配器是否可用
                    callback && _this.startSearch(callback)
                } else {
                    uni.showToast({
                        title: '本机蓝牙不可用',
                        duration: 2000,
                        icon: 'none'
                    });
                }
            },
            fail(err) {
                uni.showToast({
                    title: '本机蓝牙不可用',
                    duration: 2000,
                    icon: 'none'
                });
            }
        });
    },
    // 初始化蓝牙
    init: () => {
        const _this = printInteraction;
        uni.openBluetoothAdapter({
            success(res) {
                uni.getBluetoothAdapterState({
                    success(res) {
                        if (res.available) { // 蓝牙适配器是否可用
                            if (res.discovering) { // 蓝牙适配器是否处于搜索状态
                                //  立即停止搜索 节约电
                                _this.stopSearch();
                            }
                        }
                    }
                });
            },
            fail(err) {
                setTimeout(function () {
                    uni.showToast({
                        title: '蓝牙打开失败，请打开蓝牙',
                        duration: 2000,
                        icon: 'none'
                    });
                }, 200)
            }
        })
    },
    // 搜索附近蓝牙，并获取蓝牙列表
    startSearch: (callback) => {
        const _this = printInteraction;
        uni.showLoading({
            title: '正在搜索...'
        });
        uni.startBluetoothDevicesDiscovery({ // 开始搜索蓝牙设备
            allowDuplicatesKey: true,
            powerLevel: 'high',
            success(res) {
                setTimeout(function () {
                    uni.getBluetoothDevices({ // 获取蓝牙列表
                        success(re) {
                            callback(re)
                        },
                        fail(err) {
                            uni.showToast({
                                title: '获取设备失败',
                                duration: 2000,
                                icon: 'error'
                            });
                        }
                    });
                    _this.stopSearch();
                    uni.hideLoading();
                }, 5000);
            },
            fail(err) {
                uni.showToast({
                    title: '搜索失败',
                    duration: 2000,
                    icon: 'error'
                });
            }
        })
    },
    // 连接蓝牙设备
    connectDevice: (device_id) => {
        const _this = printInteraction;
        if (_this.device_id) {
            // 对刚才的连接设备进行断开
            _this.breakConnction();
        }
        if (device_id) {
            uni.showLoading({
                title: '正在连接'
            });
            uni.createBLEConnection({
                // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
                deviceId:device_id,
                success(res) {
                    _this.device_id = device_id;
                    uni.showToast({
                        title: '连接成功',
                        duration: 2000,
                        icon: 'error'
                    });
                    // 安卓设备 需要等待1.5秒之后
                    _this.getDeviceService();
                },
                fail(err) {
                    uni.showToast({
                        title: `连接失败！${err.code}`,
                        duration: 2000,
                        icon: 'none'
                    });
                },
                complete() {
                    uni.hideLoading();
                }
            });
        } else {
            uni.showToast({
                title: '请选择蓝牙设备',
                duration: 2000,
                icon: 'error'
            });
        }
    },
    // 获取蓝牙设备所有服务
    getDeviceService: () => {
        const _this = printInteraction;
        uni.getBLEDeviceServices({
            deviceId: _this.device_id,
            success(res) {
                _this.services = res.services;
                res.services.some(item => {
                    if (item.isPrimary) {
                        _this.service_id = item.uuid;
                        return true;
                    }
                });
                _this.getDeviceCharacter();
            }
        })
    },
    // 获取连接设备服务的所有特征值
    getDeviceCharacter: () => {
        const _this = printInteraction;
        uni.getBLEDeviceCharacteristics({
            deviceId: _this.device_id,
            serviceId: _this.service_id,
            success(res) {
                let notify_id, write_id, read_id;
                res.characteristics.forEach(item => {
                    if (item.properties.notify) {
                        notify_id = item.uuid;
                    }
                    if (item.properties.write) {
                        write_id = item.uuid;
                    }
                    if (item.properties.read) {
                        read_id = item.uuid;
                    }
                });
                if (notify_id != null && write_id != null) {
                    _this.notify_id = notify_id;
                    _this.write_id = write_id;
                    _this.read_id = read_id;
                    if (_this.connFlag) { // 发送失败进来自动再次点击 | 或手动点击按钮重新打印
                        _this.printer(_this.stringData, _this.callback);
                    }
                }
            },
            fail(err) {
                // _this.getDeviceService(); // 再次获取服务uuid（可能导致死循环 需要进行判断）
                uni.showToast({
                    title: err.code || '没有找到特征值',
                    duration: 2000,
                    icon: 'error'
                });
            }
        })
    },
    // 字符串转为ArrayBuffer
    stringToArrayBuffer: (str) => {
        const len = str.length * 2; // 一个中文占 二个字节， 其它字母 占二个字节
        const buf = new ArrayBuffer(len);
        const bufView = new Uint8Array(buf);
        for (let i = 0, strLen = str.length; i < strLen; i++) {
            // console.log('1',str.charCodeAt(i)); // 对特殊字符不支持 如：表情emoji,麻将图案等
            // console.log('2',str.codePointAt(i)); // 对特殊字符可以支持
            bufView[i] = str.charCodeAt(i);
        }
        return buf;
    },
    // 开始打印
    printer: (stringData, callback) => {
        const _this = printInteraction;
        if (!_this.device_id) {
            uni.showToast({
                title: "请选择蓝牙设备",
                duration: 2000,
                icon: 'error'
            });
            return;
        }
        uni.showLoading({
            title: '正在打印'
        });
        _this.connFlag = true;
        _this.stringData = stringData;
        _this.callback = callback;
        let buffer = null;
        stringData.forEach(item => {
            _this._writeBLECharacteristicValue(_this.stringToArrayBuffer(item));
        });
    },
    _writeBLECharacteristicValue: (buffer) => {
        const _this = printInteraction;
        // 字节长度小于等于20 只调用一次
        if (buffer.byteLength <= 20) {
            uni.writeBLECharacteristicValue({
                deviceId: _this.device_id,
                serviceId: _this.service_id,
                characteristicId: _this.notify_id,
                value: buffer,
                writeType: "write", //iOS 优先 write，安卓优先 writeNoResponse
                success(res) {
                    _this.connFlag = false;
                    _this.callback();
                },
                fail(err) {
                    // 换一个uuid获取特征值重新写入 （或者 手动去点击打印，可能需要连续点击多次）
                    if (_this.services.length) {
                        _this.services.splice(0, 1);
                        _this.services.some(item => {
                            if (item.isPrimary) {
                                _this.service_id = item.uuid;
                                return true;
                            }
                        });
                        _this.getDeviceCharacter();
                    }
                },
                complete() {
                    uni.hideLoading();
                }
            })
        } else {
            // 进行分包 最大20字节长度
            const newBuffer = buffer.slice(20);
            const writeBuffer = buffer.slice(0, 20);
            uni.writeBLECharacteristicValue({
                deviceId: _this.device_id,
                serviceId: _this.service_id,
                characteristicId: _this.notify_id,
                value: writeBuffer,
                writeType: "write", //iOS 优先 write，安卓优先 writeNoResponse
                success(res) {
                    // console.log('递归发送成功 继续发送');
                    _this._writeBLECharacteristicValue(newBuffer);
                },
                fail(err) {
                    // console.log('递归发送失败', err.code);
                    // 一旦发生失败，就要重新发送一遍，（另有需求断点发送 可保存newBuffer变量）
                    uni.hideLoading();
                    if (_this.services.length) {
                        _this.services.splice(0, 1);
                        _this.services.some(item => {
                            if (item.isPrimary) {
                                _this.service_id = item.uuid;
                                return true;
                            }
                        });
                        _this.getDeviceCharacter();
                    }
                }
            })
        }
    },
    // 停止搜索
    stopSearch: () => {
        uni.stopBluetoothDevicesDiscovery({
            success(res) {}
        })
    },
    // 关闭蓝牙适配器
    closeBluetoothAdapter: () => {
        uni.closeBluetoothAdapter({
            success(res) {
                console.log('关闭蓝牙适配器')
            }
        })
    },
    // 断开连接
    breakConnction: () => {
        const _this = printInteraction;
        if (_this.device_id) {
            uni.closeBLEConnection({
                deviceId: _this.device_id,
                success() {
                    _this.connFlag = false;
                }
            });
        }
    },
}

export default printInteraction;