package com.grkj.iscs.ble

import android.app.Application
import android.bluetooth.BluetoothGatt
import android.os.Build
import android.util.Log
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleGattCallback
import com.clj.fastble.callback.BleMtuChangedCallback
import com.clj.fastble.data.BleDevice
import com.clj.fastble.exception.BleException
import com.clj.fastble.scan.BleScanRuleConfig
import com.grkj.iscs.model.Constants.BLE_LOCAL_NAME
import com.grkj.iscs.ble.BleConst.INDICATE_UUID
import com.grkj.iscs.ble.BleConst.MTU
import com.grkj.iscs.ble.BleConst.SERVICE_UUID
import com.grkj.iscs.extentions.toHexStrings
import com.grkj.iscs.util.log.LogUtil

/**
 * 蓝牙工具类
 */
class BleUtil private constructor() {

    companion object {
        var instance: BleUtil? = null
            get() {
                if (field == null) field = BleUtil()
                return field
            }
            private set
    }

    fun initBle(application: Application?) {
        try {
            BleManager.getInstance().init(application)
            BleManager.getInstance().enableLog(false)
                .setConnectOverTime(10 * 1000L)
                .setReConnectCount(3, 300) // 设置重新连接次数和间隔时间，默认为0次，不重连
                .setSplitWriteNum(500)
                .operateTimeout = 60 * 60 * 1000 // 设置操作readRssi、setMtu、write、read、notify、indicate的超时时间（毫秒）
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
                //Android 12及以上不允许添加过滤器
                val bleScanRuleConfig = BleScanRuleConfig.Builder()
//                .setServiceUuids(arrayOf(UUID.fromString(BLUETOOTH_SERVICEUUID)))
                    .setDeviceName(true, BLE_LOCAL_NAME)
                    .build()
                BleManager.getInstance().initScanRule(bleScanRuleConfig)
            }
        } catch (e: Exception) {
            Log.d("initBlueTooth", "蓝牙初始化：${e.message}")
        }
    }

    fun scan(bleScanCallback: CustomBleScanCallback) {
        if (BleManager.getInstance().isSupportBle) {
            if (BleManager.getInstance().isBlueEnable) {
                BleManager.getInstance().scan(bleScanCallback)
            } else {
                bleScanCallback.onPrompt("请打开您的蓝牙后重试")
            }
        } else {
            bleScanCallback.onPrompt("您的设备不支持蓝牙设备")
        }
    }

    fun connectBySelect(bleDevice: BleDevice?, bleGattCallback: CustomBleGattCallback) {
        if (BleManager.getInstance().isSupportBle) {
            if (BleManager.getInstance().isBlueEnable) {
                BleManager.getInstance().connect(bleDevice, bleGattCallback)
            } else {
                bleGattCallback.onPrompt("请打开您的蓝牙后重试")
            }
        } else {
            bleGattCallback.onPrompt("您的设备不支持蓝牙设备")
        }
    }

    fun connectByMac(mac: String?, bleGattCallback: CustomBleGattCallback) {
        if (BleManager.getInstance().isSupportBle) {
            if (BleManager.getInstance().isBlueEnable) {
                BleManager.getInstance().connect(mac, bleGattCallback)
            } else {
                bleGattCallback.onPrompt("请打开您的蓝牙后重试")
            }
        } else {
            bleGattCallback.onPrompt("您的设备不支持蓝牙设备")
        }
    }

    fun setMtu(bleDevice: BleDevice) {
        BleManager.getInstance().setMtu(bleDevice, MTU, object : BleMtuChangedCallback() {
            override fun onSetMTUFailure(exception: BleException?) {
//                indicate()
            }

            override fun onMtuChanged(mtu: Int) {
//                indicate()
            }
        })
    }

    fun indicate(bleDevice: BleDevice,
                 serviceUUID: String = SERVICE_UUID,
                 indicateUUID: String = INDICATE_UUID,
                 isStart: Boolean = true,
                 indicateCallback: CustomBleIndicateCallback?) {
        // stopIndicate包含removeIndicateCallback
//        BleManager.getInstance().removeIndicateCallback(bleDevice, indicateUUID)
        BleManager.getInstance().stopIndicate(bleDevice, serviceUUID, indicateUUID)
        if (!isStart) {
            return
        }
        if (!BleManager.getInstance().isSupportBle) {
            indicateCallback?.onPrompt("该设备不支持蓝牙BLE")
            return
        }

        if (!BleManager.getInstance().isBlueEnable) {
            indicateCallback?.onPrompt("蓝牙已关闭，请打开蓝牙后重试")
            return
        }
        if (BleManager.getInstance().isConnected(bleDevice.mac)) {
            BleManager.getInstance().indicate(bleDevice, serviceUUID, indicateUUID, indicateCallback)
        } else {
            BleManager.getInstance().connect(bleDevice.mac, object : BleGattCallback() {
                override fun onStartConnect() {}
                override fun onConnectFail(bleDevice: BleDevice, exception: BleException) {
                    BleManager.getInstance().removeConnectGattCallback(bleDevice)
                    indicateCallback?.onConnectPrompt("连接失败!请检查设备是否打开,并尝试重新连接 : $exception")
                }

                override fun onConnectSuccess(bleDevice: BleDevice, gatt: BluetoothGatt, status: Int) {
                    BleManager.getInstance().removeConnectGattCallback(bleDevice)
                    BleManager.getInstance().indicate(bleDevice, serviceUUID, indicateUUID, indicateCallback)
                }

                override fun onDisConnected(isActiveDisConnected: Boolean, device: BleDevice, gatt: BluetoothGatt, status: Int) {
                    BleManager.getInstance().removeConnectGattCallback(device)
                    indicateCallback?.onDisConnectPrompt("连接断开!请检查设备状态,并尝试重新连接!")
                }
            })
        }
    }


    fun write(bleDevice: BleDevice,
              serviceUUID: String = SERVICE_UUID,
              writeUUID: String = INDICATE_UUID,
              cmd: ByteArray?,
              writeCallback: CustomBleWriteCallback?
    ) {
        LogUtil.i("ble_write : ${cmd?.toHexStrings()}")
        cmd ?: return
        if (!BleManager.getInstance().isSupportBle) {
            writeCallback?.onPrompt("该设备不支持蓝牙BLE")
            return
        }

        if (!BleManager.getInstance().isBlueEnable) {
            writeCallback?.onPrompt("蓝牙已关闭，请打开蓝牙后重试")
            return
        }
        if (BleManager.getInstance().isConnected(bleDevice.mac)) {
            BleManager.getInstance().write(bleDevice, serviceUUID, writeUUID, cmd, writeCallback)
        } else {
            BleManager.getInstance().connect(bleDevice.mac, object : BleGattCallback() {
                override fun onStartConnect() {}
                override fun onConnectFail(bleDevice: BleDevice, exception: BleException) {
                    BleManager.getInstance().removeConnectGattCallback(bleDevice)
                    writeCallback?.onConnectPrompt("连接失败!请检查设备是否打开,并尝试重新连接 : $exception")
                }

                override fun onConnectSuccess(bleDevice: BleDevice, gatt: BluetoothGatt, status: Int) {
                    BleManager.getInstance().removeConnectGattCallback(bleDevice)
                    BleManager.getInstance().write(bleDevice, serviceUUID, writeUUID, cmd, writeCallback)
                }

                override fun onDisConnected(isActiveDisConnected: Boolean, device: BleDevice, gatt: BluetoothGatt, status: Int) {
                    BleManager.getInstance().removeConnectGattCallback(device)
                    writeCallback?.onDisConnectPrompt("连接断开!请检查设备状态,并尝试重新连接!")
                }
            })
        }
    }
}