// 引入必要的微信小程序 API
// const wx = require('wx');

class bleManager {
    constructor() {
        this.hasPermission = false;
        this.isAvailable = false;
        this.scanDevices = [];
        this.device = null;
    }

    // 检查蓝牙权限
    async checkBluetoothPermission(callback) {
        // return new Promise((resolve, reject) => {
        // 获取蓝牙权限
        const _app = getApp();
        wx.getSetting({
            success(res) {
                if (res.authSetting["scope.bluetooth"]) {
                    _app.globalData.scopeBluetooth = true;
                    this.hasPermission = true;
                    // console.log('checkBluetoothPermission success, now is', res)
                    if (callback) {
                        callback(true);
                    }
                    // resolve(true);

                } else if (res.authSetting["scope.bluetooth"] === undefined) {
                    _app.globalData.scopeBluetooth = false;
                    this.hasPermission = false;
                    if (callback) {
                        callback(false);
                    }
                    wx.authorize({
                        scope: "scope.bluetooth",
                        complete() {
                            this.checkBluetoothPermission()
                            // resolve(_this.checkBluetoothPermission());

                        }
                    });

                } else {
                    _this.globalData.scopeBluetooth = false;
                    this.hasPermission = false;
                    if (callback) {
                        callback(false);
                    }
                    wx.showModal({
                        title: '请打开系统蓝牙进行配网',
                        content: '如已打开蓝牙仍然弹框，请尝试重启小程序',
                        success(res) {
                            if (res.confirm) {
                                console.log('用户点击确定')
                                wx.openSetting({
                                    complete() {
                                        // _this.getBluetoothStatus();
                                    }
                                })
                            } else if (res.cancel) {
                                console.log('用户点击取消')
                            }
                        }
                    })
                    // resolve(false);
                };
            }
        })
        // })

    }

    // 初始化蓝牙适配器
    async initBluetoothAdapter(callback) {
        let _this = this
        return new Promise((resolve, reject) => {
            wx.openBluetoothAdapter({
                success: (res) => {
                    _this.isAvailable = true;
                    // console.log('adapterState success, now is', res)
                    if (callback) {
                        callback(true);
                    }
                    resolve(true);
                },
                fail: (err) => {
                    _this.isAvailable = false;
                    console.log('adapterState fail, now is', err)
                    if (callback) {
                        callback(false);
                    }
                    reject(false);
                }
            });
            wx.onBluetoothAdapterStateChange(function (res) {
                console.log('adapterState changed, now is', res)
                if (callback) {
                    callback(res.available ?? false);
                }
                _this.isAvailable = res.available ?? false

            })
        });
    }

    closeBle() {
        wx.closeBluetoothAdapter()
    }

    // 获取已连接的蓝牙设备
    getConnectedDevices() {
        if (!this.isAvailable && !this.hasPermission) {
            return [];
        }
        return new Promise((resolve, reject) => {
            wx.getConnectedBluetoothDevices({
                // services: ["FFC0", "ffc0", "FFC1", "FFC2", "ffc1", "ffc2", "AB00", "ab00", "AB01", "AB02", "FFF1", "fff1", "FFE2", "FFE5",],
                services: ["ab00", "ffe5", "1111", "FFC0", "FFC1", "FFF1",],
                // services: [],
                // services: [
                //     "0000ab00-0000-1000-8000-00805f9b34fb",
                //     "0000ffc0-0000-1000-8000-00805f9b34fb",
                //     "0000FFF0-0000-1000-8000-00805F9B34FB",
                //     "0000FFF1-0000-1000-8000-00805F9B34FB",
                //     "0000FFE5-0000-1000-8000-00805F9B34FB",
                // ],
                success: (res) => {
                    let newDevices = this.fiterDevice(res)
                    console.log('已连接的蓝牙设备:', newDevices);
                    resolve(newDevices);
                },
                fail: (err) => {
                    console.error('获取已连接的蓝牙设备失败:', err);
                    reject([]);
                }
            });
        });
    }

    // 获取获取在蓝牙模块生效期间所有搜索到的蓝牙设备。包括已经和本机处于连接状态的设备。
    getAllConnectedDevices() {
        if (!this.isAvailable && !this.hasPermission) {
            return [];
        }
        return new Promise((resolve, reject) => {
            wx.getBluetoothDevices({
                success: (res) => {
                    // const connectedDevices = res.devices.map(device => ({
                    //     deviceId: device.deviceId,
                    //     name: device.name || device.localName
                    // }));
                    console.log('已扫描过的蓝牙设备:', res);
                    let newDevices = this.fiterDevice(res)

                    resolve(newDevices);
                },
                fail: (err) => {
                    console.error('已扫描过的蓝牙设备失败:', err);
                    reject([]);
                }
            });
        });
    }

    // 断开与指定设备的连接
    disconnect(deviceId) {
        return new Promise((resolve, reject) => {
            wx.closeBLEConnection({
                deviceId: deviceId,
                success: (res) => {
                    this.device = null;
                    console.log('断开连接成功:', res);
                    resolve(res);
                },
                fail: (err) => {
                    console.error('断开连接失败:', err);
                    reject(new Error('断开连接失败'));
                }
            });
        });
    }

    // 发送数据到指定设备
    sendData(data) {
        return new Promise((resolve, reject) => {
            const buffer = new ArrayBuffer(data.length);
            const view = new Uint8Array(buffer);
            for (let i = 0; i < data.length; i++) {
                view[i] = data[i];
            }
            console.log('开始发送数据:', data, view);
            wx.writeBLECharacteristicValue({
                deviceId: this.device.deviceId,
                serviceId: this.device.serviceId,
                characteristicId: this.device.characteristicId,
                value: buffer,
                success: (res) => {
                    console.log('数据发送成功:');
                    resolve(res);
                },
                fail: (err) => {
                    console.error('数据发送失败:', err);
                    reject(new Error('数据发送失败'));
                }
            });
        });
    }

    async getSetting() {
        const _this = this;
        return new Promise((resolve, reject) => {

            wx.getSetting({
                success(res) {
                    if (res.authSetting["scope.userFuzzyLocation"]) {
                        // 成功
                        // _this.getBluetoothStatus();
                        console.log("有定位权限")
                        resolve(true);

                    } else if (res.authSetting["scope.userFuzzyLocation"] === undefined) {

                        wx.authorize({
                            scope: "scope.userFuzzyLocation",
                            success() {
                                console.log("再次获取定位权限")
                                resolve(_this.getSetting());

                            }
                        });
                    } else {

                        wx.showModal({
                            title: '请打开系统位置获取定位权限',
                            success(res) {
                                if (res.confirm) {
                                    console.log('用户点击确定')
                                    wx.openSetting({
                                        complete() {
                                            // _this.getSetting();
                                            // resolve(_this.getSetting());

                                        }
                                    })
                                } else if (res.cancel) {
                                    console.log('用户点击取消');
                                }
                            }
                        })
                        console.log("没有有定位权限")
                        reject(false);

                    }
                }
            })

        });

    }
    // 开始搜索蓝牙设备
    async startScan(success, fail) {

        let open = await this.getSetting()
        if (!open) {
            if (fail) {
                fail("需要先开启定位");
            }
            console.log('需要先开启定位');
        }
        if (!this.isAvailable && !this.hasPermission) {
            return false;
        }
        wx.startBluetoothDevicesDiscovery({
            // services: ["ffc0", "ab00", "ffe5"],
            success: (res) => {
                // this.onBluetoothDeviceFound();
                console.log('蓝牙设备搜索已启动:', res);
                if (success) {
                    success(res);
                }

                // resolve(res);
            },
            fail: (err) => {
                if (fail) {
                    if (err.errno == 1509008) {
                        wx.showToast({
                            title: '搜索蓝牙需要先开启定位权限',
                            icon: 'none',
                            duration: 2000
                        })
                    }
                    fail(err);
                }
                console.log('启动蓝牙设备搜索失败', err ?? "err is null");

                // reject(new Error('启动蓝牙设备搜索失败', err ?? "err is null"));
            }
        });
    }

    // 监听发现新设备的事件
    onBluetoothDeviceFound(callback) {
        wx.onBluetoothDeviceFound((res) => {

            let newDevices = this.fiterDevice(res)
            // this.devices.push(...devices);
            if (newDevices.length > 0) {
                // console.log('发现设备:', newDevices[0].deviceId, newDevices[0].uuid);
            }
            if (callback) {
                callback(newDevices);
            }
        });
    }
    ab2hex(buffer) {
        var hexArr = Array.prototype.map.call(
            new Uint8Array(buffer),
            function (bit) {
                return ('00' + bit.toString(16)).slice(-2)
            }
        )
        return hexArr.join('');
    }
    fiterDevice(res) {
        var devices = res.devices.filter(device => {
            const name = device.name || '';
            const localName = device.localName || '';
            let isNot = this.isNotEmpty(name) || this.isNotEmpty(localName);
            if (isNot) {
                let mac = this.ab2hex(device.advertisData)
                // console.log(mac)
                device.mac = mac
            }
            return isNot
        });

        let newDevices = devices.map((device) => {
            let uuid = device.advertisServiceUUIDs[0] ?? ""
            return {
                deviceId: device.deviceId,
                name: device.name,
                localName: device.localName,
                uuid: uuid,
                mac: device.mac,
                connectable: device.connectable
            }
        });
        return newDevices
    }
    isNotEmpty(name) {
        let isNot = (name !== ''
            && (name.includes("猫王") ||
                name.includes("MW_") ||
                name.includes("妙播") ||
                name.includes("AirSmart") ||
                name === "le")
        )
        // if (!isNot && name !== '') {
        //     console.log('不是猫王设备名称:', name)
        // }
        return isNot;
    }
    // 连接到指定设备
    connectToDevice(device) {

        return new Promise((resolve, reject) => {
            console.log("开始连接蓝牙：", device.deviceId)
            wx.createBLEConnection({
                deviceId: device.deviceId,
                success: (res) => {
                    this.device = device
                    console.log('连接成功:', res);
                    resolve(true);
                },
                fail: (err) => {
                    this.device = null
                    console.error('连接失败:', err);
                    reject(false);
                }
            });
        });
    }

    // 停止搜索
    stopScan() {

        return new Promise((resolve, reject) => {

            wx.stopBluetoothDevicesDiscovery({
                success: (res) => {
                    console.log('停止搜索成功:', res);
                    resolve(res);
                },
                fail: (err) => {
                    console.error('停止搜索失败:', err);
                    reject(new Error('停止搜索失败'));
                }
            });

        });
    }
    closeBle() {
        wx.closeBluetoothAdapter({
            success(res) {
                console.log(res)
            }
        })
    }

    // 发现服务
    discoverServices(deviceId) {
        console.log('发现服务:', deviceId);

        return new Promise((resolve, reject) => {
            wx.getBLEDeviceServices({
                deviceId: deviceId,
                success: (res) => {
                    this.device.services = res.services;
                    let service_id = "";
                    for (let i = 0; i < res.services.length; i++) {
                        if (res.services[i].uuid.toUpperCase().indexOf("AB00") != -1
                            || res.services[i].uuid.toUpperCase().indexOf("FFC0") != -1
                        ) {
                            service_id = res.services[i].uuid;
                            break;
                        }
                    }
                    this.device.serviceId = service_id;
                    console.log('发现服务:', service_id);

                    resolve(service_id);
                    // resolve(res.services);
                },
                fail: (err) => {
                    this.device.serviceId = null;

                    console.error('发现服务失败:', err);
                    reject([]);
                }
            });
        });
    }

    // 发现特征值 read / write
    discoverCharacteristics(deviceId, serviceId) {
        console.log('发现特征值:' + deviceId + " ,  " + serviceId);

        // if (deviceId !== this.device.deviceId) {
        //     console.log('设备id不匹配')
        //     return false
        // }
        return new Promise((resolve, reject) => {
            wx.getBLEDeviceCharacteristics({
                deviceId: deviceId,
                serviceId: serviceId,
                success: (res) => {
                    // this.characteristics[serviceId] = res.characteristics;
                    console.log('发现特征值2:', res);
                    this.device.characteristics = res.characteristics;

                    resolve(res.characteristics);
                },
                fail: (err) => {
                    this.device.characteristics = null;
                    console.error('发现特征值失败:', err);
                    reject("");
                }
            });
        });
    }

    // 读取特征值
    readCharacteristicValue(characteristicId) {

        console.log('开始读取特征值', characteristicId)
        return new Promise((resolve, reject) => {
            wx.readBLECharacteristicValue({
                deviceId: this.device.deviceId,
                serviceId: this.device.serviceId,
                characteristicId: characteristicId,
                success: (res) => {
                    const name = this.parseBLEValue(res.value); // 解析读取到的值

                    console.log('读取特征值成功:', name, res);
                    resolve(res);
                },
                fail: (err) => {
                    console.error('读取特征值失败:', err);
                    reject("");
                }
            });
        });
    }
    // 解析读取到的设备名称
    parseBLEValue(buffer) {
        return String.fromCharCode.apply(null, new Uint8Array(buffer));
    }
    // 监听特征值变化
    notifyCharacteristicValueChange(characteristicId, callback) {
        console.log('监听特征值变化:', characteristicId);
        wx.notifyBLECharacteristicValueChange({
            deviceId: this.device.deviceId,  //设备mac   IOS和安卓系统不一样
            serviceId: this.device.serviceId,     //服务通道，这里主要是notify
            characteristicId: characteristicId,     //notify uuid
            state: true,
            success: function (res) {
                console.log("开启notify 成功")
                //TODO  onBLECharacteristicValueChange  监听特征值 设备的数据在这里获取到
                wx.onBLECharacteristicValueChange(function (characteristic) {
                    let buffer = characteristic.value
                    let dataView = new DataView(buffer)
                    let dataResult = []
                    for (let i = 0; i < dataView.byteLength; i++) {
                        // console.log("0x" + dataView.getUint8(i).toString(16))
                        // dataResult.push("0x" + dataView.getUint8(i).toString(16))
                        dataResult.push(dataView.getUint8(i))
                    }
                    const result = dataResult
                    console.log("拿到的数据：", result)

                    if (callback) {
                        callback(result)
                    }
                })
            },
            fail: function (res) {
                console.log("订阅特征失败：", res)

            }
        })
    }

    setWrite(wirte, characteristicId) {
        console.log('写入特征值:', characteristicId)
        this.device.wirte = wirte
        this.device.characteristicId = characteristicId;
    }

}

const ble = new bleManager();

// 导出 bleManager 类
module.exports = ble;
