import { reactive, ref } from 'vue';
import BtErrorMap from '@/enums/bluetooth';
import Toast from '../utils/toast';

// #ifdef APP-PLUS | APP | APP-NVUE | APP-PLUS-NVUE
const BluetoothAdapter : any = plus.android.importClass("android.bluetooth.BluetoothAdapter");
const BAdapter : any = BluetoothAdapter.getDefaultAdapter();
// #endif

export interface ErrorType {
    errMsg : string;
    code : number
}

export interface DeviceInfo {
    /**
     * 蓝牙设备名称,某些设备可能没有
     */
    name : string;
    /**
     * 用于区分设备的 id
     */
    deviceId : string;
    /**
     * 当前蓝牙设备的信号强度
     */
    RSSI : number;
    /**
     * 当前蓝牙设备的广播数据段中的ManufacturerData数据段 (注意:vConsole 无法打印出 ArrayBuffer 类型数据)
     */
    advertisData : any[];
    /**
     * 当前蓝牙设备的广播数据段中的ServiceUUIDs数据段
     */
    advertisServiceUUIDs : any[];
    /**
     * 当前蓝牙设备的广播数据段中的LocalName数据段
     */
    localName : string;
    /**
     * 当前蓝牙设备的广播数据段中的ServiceData数据段
     */
    serviceData : any[];
    /**
     * 设备状态 0=正常;1=连接中;2=连接成功
     */
    status : 0 | 1 | 2 | 3;
}

export interface StateType {
    searching : boolean;
    devices : DeviceInfo[];
    bindDevice : Record<string, any>;
    searchInit : boolean;
    available : boolean;
    discovering : boolean;
    connecting : boolean;
}

/**
 * 集中状态管理
 */
export const state = reactive<StateType>({
    searching: true, // 搜索状态
    devices: [], // 搜索到的蓝牙设备数据
    // bindDevice: { name: 'GAN 12ui CC0' }
    bindDevice: null, // 已连接的魔方
    searchInit: false, // 搜索初始化
    available: false, // 蓝牙适配器是否可用
    discovering: false, // 蓝牙适配器是否处于搜索状态
    connecting: false, // 设备连接状态,连接中不可再次连接
})

let searchTimer : any; // 搜索计时器

/**
 * 捕获错误信息
 */
export const getError = (code : number) => {
    const codeKey : string = String(code)

    return BtErrorMap[codeKey].message
}

/**
 * 校验手机是否打开蓝牙
 */
export const getBluetoothStatus = () => {
    // #ifdef APP-PLUS | APP | APP-NVUE | APP-PLUS-NVUE
    return BAdapter.isEnabled()
    // #endif
}

/**
 * 校验手机是否打开蓝牙,未打开则请求权限
 */
export const openBluetooth = () => {
    return new Promise((resolve, reject) => {
        try {
            // 蓝牙未开启,打开蓝牙
            // #ifdef APP-PLUS | APP | APP-NVUE | APP-PLUS-NVUE
            if (!BAdapter.isEnabled()) {
                BAdapter.enable()
                resolve(true)
            }
            // #endif
        } catch (e) {
            reject(e)
        }
    })
}

/**
 * 初始化蓝牙模块
 */
export const initBluetooth = () => {
    return new Promise((resolve, reject) => {
        uni.openBluetoothAdapter({
            success(res) {
                console.log('蓝牙初始化', res)
                state.available = true
                resolve(res)
            },
            fail(err : ErrorType) {
                state.available = false
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}

/**
 * 开始搜寻附近的蓝牙外围设备
 */
export const startSearch = () => {
    return new Promise((resolve, reject) => {
        uni.startBluetoothDevicesDiscovery({
            success(res) {
                Toast('开始搜索蓝牙设备')
                console.log(JSON.stringify(res))
                resolve(res)
            },
            fail(err : ErrorType) {
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}

/**
 * 停止搜寻附近的蓝牙外围设备
 */
export const stopSearch = () => {
    return new Promise((resolve, reject) => {
        uni.startBluetoothDevicesDiscovery({
            success() {
                Toast('已停止搜索设备')
                resolve(true)
            },
            fail(err : ErrorType) {
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}

/**
 * 根据 uuid 获取处于已连接状态的设备
 * @param {string[]} services 蓝牙设备主 service 的 uuid 列表
 */
export const getConnect = (services : string[]) => {
    uni.getConnectedBluetoothDevices({
        services,
        success() {

        },
        fail(err : ErrorType) {
            console.log(err)
            getError(err.code)
        }
    })
}

/**
 * 监听寻找到新设备的事件
 */
export const onSearch = () => {
    uni.onBluetoothDeviceFound((devices) => {
        Toast('找到新设备')
        console.log('devices', devices)
    })
}

/**
 * 监听蓝牙适配器状态变化事件
 */
export const onBluetoothStatus = () => {
    uni.onBluetoothAdapterStateChange((res : { discovering : boolean, available : boolean }) => {
        console.log(res)
        state.available = res.available
        state.discovering = res.discovering
    })
}

/**
 * 轮询将获取到的设备存入缓存
 */
export const getSearchDevices = async () => {
    let count : number = 0
    clearInterval(searchTimer)
    searchTimer = null
    await startSearch()
    searchTimer = setInterval(async () => {
        if (count === 3) {
            clearInterval(searchTimer)
            searchTimer = null
            state.searchInit = true
            state.searching = false
            state.discovering = false
            stopSearch()
            return
        }
        await onSearchDevices()
        count++
        console.log('搜索次数:' + count)
    }, 1000)
}

/**
 * 蓝牙关闭时处理
 */
export const bluetoothCloseHandle = async () => {
    clearInterval(searchTimer)
    searchTimer = null
    state.searching = false
    state.discovering = true
    await stopSearch()
    await closeBluetooth()
}

/**
 * 连接低功耗蓝牙设备
 * @param { string } deviceId 蓝牙设备id
 */
export const createBLEConnection = (deviceId : string) => {
    if (state.connecting) return
    state.connecting = true
    let deviceIndex = state.devices.findIndex((item : DeviceInfo) => {
        return item.deviceId === deviceId
    })
    state.devices[deviceIndex].status = 1
    return new Promise((resolve, reject) => {
        uni.createBLEConnection({
            deviceId: deviceId,
            timeout: 10000, // ms
            success(res) {
                resolve(res)
                console.log(res)
                state.devices[deviceIndex].status = 2
                state.connecting = false
                Toast.success("已连接")
            },
            fail(err : ErrorType) {
                state.devices[deviceIndex].status = 3
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}


/**
 * 获取在蓝牙模块生效期间所有已发现的蓝牙设备
 * 包括已经和本机处于连接状态的设备
 */
export const onSearchDevices = () => {
    return new Promise((resolve, reject) => {
        uni.getBluetoothDevices({
            success(res) {
                resolve(res)
                console.log(res)
                state.devices = res.devices.map((item : DeviceInfo) => {
                    item.status = 0
                    return item
                }).filter((item : DeviceInfo) => item.name !== '')
            },
            fail(err : ErrorType) {
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}

/**
 * 获取本机蓝牙适配器状态
 */
export const getAdapterState = () => {
    return new Promise((resolve, reject) => {
        uni.getBluetoothAdapterState({
            success(res) {
                resolve(res)
                console.log(res)
            },
            fail(err : ErrorType) {
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}

/**
 * 关闭蓝牙模块
 * 调用该方法将断开所有已建立的连接并释放系统资源
 * 建议在使用蓝牙流程后,与 uni.openBluetoothAdapter 成对调用
 */
export const closeBluetooth = () => {
    return new Promise((resolve, reject) => {
        uni.closeBluetoothAdapter({
            success(res) {
                resolve(res)
                console.log(res)
            },
            fail(err : ErrorType) {
                console.error(getError(err.code))
                reject(getError(err.code))
            }
        })
    })
}