import { BleManager, Device, State, Characteristic, BleError } from 'react-native-ble-plx';
import { PermissionsAndroid, Platform } from 'react-native';
import base64 from 'base-64';
import utf8 from 'utf8';

// 定义命令类型
export enum CommandType {
    REBOOT = '11reboot',
    OPEN = '11open',
    CLOSE = '11close',
    PLAY = '11play1@'
}

// 定义连接状态类型
export enum ConnectionState {
    DISCONNECTED = 'disconnected',
    CONNECTING = 'connecting',
    CONNECTED = 'connected',
    DISCONNECTING = 'disconnecting'
}

class BluetoothManager {
    private static instance: BluetoothManager;
    private manager: BleManager;
    private isScanning: boolean = false;
    private connectedDevice: Device | null = null;
    private isInitializing: boolean = false;
    private stateSubscription: any = null;
    private initialized: boolean = false;
    private scanTimeout: NodeJS.Timeout | null = null;
    private writeCharacteristic: Characteristic | null = null;
    private connectionState: ConnectionState = ConnectionState.DISCONNECTED;
    private connectionStateListeners: ((state: ConnectionState) => void)[] = [];
    private deviceDisconnectListener: any = null;

    // 蓝牙服务和特征值 UUID
    private readonly SERVICE_UUID = "000000FF-0000-1000-8000-00805F9B34FB";
    private readonly CHARACTERISTIC_UUID = "0000FF01-0000-1000-8000-00805F9B34FB";

    private constructor() {
        this.manager = new BleManager();
    }

    public static getInstance(): BluetoothManager {
        if (!BluetoothManager.instance) {
            BluetoothManager.instance = new BluetoothManager();
        }
        return BluetoothManager.instance;
    }

    // 添加连接状态监听
    addConnectionStateListener(listener: (state: ConnectionState) => void) {
        this.connectionStateListeners.push(listener);
        // 立即触发一次当前状态
        listener(this.connectionState);
        return () => {
            const index = this.connectionStateListeners.indexOf(listener);
            if (index > -1) {
                this.connectionStateListeners.splice(index, 1);
            }
        };
    }

    // 更新连接状态
    private updateConnectionState(state: ConnectionState) {
        this.connectionState = state;
        this.connectionStateListeners.forEach(listener => listener(state));
    }

    // 设置设备断开监听
    private setupDisconnectionListener(device: Device) {
        if (this.deviceDisconnectListener) {
            this.deviceDisconnectListener.remove();
        }

        this.deviceDisconnectListener = device.onDisconnected((error: BleError | null) => {
            console.log('设备断开连接:', error ? error.message : '正常断开');
            this.connectedDevice = null;
            this.writeCharacteristic = null;
            this.updateConnectionState(ConnectionState.DISCONNECTED);
        });
    }

    private stringToBase64(str: string): string {
        try {
            const bytes = utf8.encode(str);
            const encoded = base64.encode(bytes);
            return encoded;
        } catch (error) {
            console.error('String to base64 conversion failed:', error);
            throw error;
        }
    }

    async requestPermissions(): Promise<boolean> {
        if (Platform.OS === 'android') {
            try {
                if (Platform.Version >= 31) {
                    const locationPermission = await PermissionsAndroid.request(
                        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                        {
                            title: '位置权限',
                            message: '扫描蓝牙设备需要位置权限',
                            buttonNeutral: '稍后询问',
                            buttonNegative: '取消',
                            buttonPositive: '确定'
                        }
                    );

                    const scanPermission = await PermissionsAndroid.request(
                        PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
                        {
                            title: '蓝牙扫描权限',
                            message: '需要蓝牙扫描权限以发现设备',
                            buttonNeutral: '稍后询问',
                            buttonNegative: '取消',
                            buttonPositive: '确定'
                        }
                    );

                    const connectPermission = await PermissionsAndroid.request(
                        PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
                        {
                            title: '蓝牙连接权限',
                            message: '需要蓝牙连接权限以连接设备',
                            buttonNeutral: '稍后询问',
                            buttonNegative: '取消',
                            buttonPositive: '确定'
                        }
                    );

                    return (
                        locationPermission === PermissionsAndroid.RESULTS.GRANTED &&
                        scanPermission === PermissionsAndroid.RESULTS.GRANTED &&
                        connectPermission === PermissionsAndroid.RESULTS.GRANTED
                    );
                } else {
                    const granted = await PermissionsAndroid.request(
                        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                        {
                            title: '位置权限',
                            message: '扫描蓝牙设备需要位置权限',
                            buttonNeutral: '稍后询问',
                            buttonNegative: '取消',
                            buttonPositive: '确定'
                        }
                    );
                    return granted === PermissionsAndroid.RESULTS.GRANTED;
                }
            } catch (err) {
                console.warn('权限请求错误:', err);
                return false;
            }
        }
        return true;
    }

    async init(): Promise<boolean> {
        if (this.initialized) {
            return true;
        }

        if (this.isInitializing) {
            return false;
        }

        try {
            this.isInitializing = true;
            const hasPermissions = await this.requestPermissions();
            
            if (!hasPermissions) {
                throw new Error('未获得必要权限');
            }

            return new Promise((resolve, reject) => {
                let subscription: any = null;
                
                this.manager.state().then(state => {
                    if (state === State.PoweredOn) {
                        this.initialized = true;
                        resolve(true);
                        return;
                    }
                    
                    subscription = this.manager.onStateChange((newState) => {
                        if (newState === State.PoweredOn) {
                            this.initialized = true;
                            if (subscription) {
                                subscription.remove();
                            }
                            resolve(true);
                        } else if (newState === State.PoweredOff) {
                            if (subscription) {
                                subscription.remove();
                            }
                            reject(new Error('请打开蓝牙'));
                        }
                    }, true);

                    setTimeout(() => {
                        if (subscription) {
                            subscription.remove();
                        }
                        reject(new Error('蓝牙初始化超时'));
                    }, 5000);
                });
            });
        } catch (error) {
            console.error('蓝牙初始化失败:', error);
            throw error;
        } finally {
            this.isInitializing = false;
        }
    }

    async startScan(onDeviceFound: (device: Device) => void): Promise<void> {
        if (this.isScanning) return;

        try {
            this.isScanning = true;
            this.manager.startDeviceScan(
                null,
                { allowDuplicates: false },
                (error, device) => {
                    if (error) {
                        console.error('扫描错误:', error);
                        this.stopScan();
                        return;
                    }
                    if (device && device.name && device.name.startsWith('BBLE')) {
                        onDeviceFound(device);
                    }
                }
            );

            if (this.scanTimeout) {
                clearTimeout(this.scanTimeout);
            }

            this.scanTimeout = setTimeout(() => {
                this.stopScan();
            }, 5000);
        } catch (error) {
            console.error('开始扫描失败:', error);
            this.isScanning = false;
            throw error;
        }
    }

    stopScan(): void {
        if (this.isScanning) {
            this.manager.stopDeviceScan();
            this.isScanning = false;
            
            if (this.scanTimeout) {
                clearTimeout(this.scanTimeout);
                this.scanTimeout = null;
            }
        }
    }

    async connectToDevice(device: Device): Promise<boolean> {
        try {
            this.updateConnectionState(ConnectionState.CONNECTING);
            console.log('开始连接设备:', device.id);
            
            // 确保之前的连接已断开
            if (this.connectedDevice) {
                this.updateConnectionState(ConnectionState.DISCONNECTING);
                await this.disconnect();
            }

            // 建立连接
            const connectedDevice = await device.connect({
                timeout: 5000,
                requestMTU: 512
            });
            
            // 设置断开连接监听
            this.setupDisconnectionListener(connectedDevice);
            
            console.log('设备已连接，开始发现服务...');
            
            // 等待服务发现完成
            await connectedDevice.discoverAllServicesAndCharacteristics();
            console.log('服务发现完成');
            
            // 验证设备是否具有所需的服务和特征
            const services = await connectedDevice.services();
            let hasRequiredService = false;
            let hasRequiredCharacteristic = false;

            for (const service of services) {
                console.log('发现服务:', service.uuid);
                if (service.uuid.toLowerCase() === this.SERVICE_UUID.toLowerCase()) {
                    hasRequiredService = true;
                    const characteristics = await service.characteristics();
                    for (const characteristic of characteristics) {
                        console.log('发现特征:', characteristic.uuid);
                        if (characteristic.uuid.toLowerCase() === this.CHARACTERISTIC_UUID.toLowerCase()) {
                            hasRequiredCharacteristic = true;
                            this.writeCharacteristic = characteristic;
                            break;
                        }
                    }
                    break;
                }
            }

            if (!hasRequiredService || !hasRequiredCharacteristic) {
                console.error('设备不具备所需的服务或特征');
                await connectedDevice.cancelConnection();
                this.updateConnectionState(ConnectionState.DISCONNECTED);
                return false;
            }

            this.connectedDevice = connectedDevice;
            this.updateConnectionState(ConnectionState.CONNECTED);
            return true;
        } catch (error) {
            console.error('连接设备失败:', error);
            this.updateConnectionState(ConnectionState.DISCONNECTED);
            return false;
        }
    }

    async sendCommand(command: CommandType): Promise<boolean> {
        if (!this.connectedDevice || !this.writeCharacteristic) {
            throw new Error('设备未连接或特征未找到');
        }

        try {
            console.log('发送命令:', command);
            const base64Data = this.stringToBase64(command);
            console.log('编码后的数据:', base64Data);
            
            await this.writeCharacteristic.writeWithResponse(base64Data);
            console.log('命令发送成功');
            return true;
        } catch (error) {
            console.error('发送命令失败:', error);
            return false;
        }
    }

    async rebootDevice(): Promise<boolean> {
        return this.sendCommand(CommandType.REBOOT);
    }

    async openDevice(): Promise<boolean> {
        return this.sendCommand(CommandType.OPEN);
    }

    async closeDevice(): Promise<boolean> {
        return this.sendCommand(CommandType.CLOSE);
    }

    async playResponse(): Promise<boolean> {
        return this.sendCommand(CommandType.PLAY);
    }

    async disconnect(): Promise<void> {
        if (this.connectedDevice) {
            try {
                this.updateConnectionState(ConnectionState.DISCONNECTING);
                await this.connectedDevice.cancelConnection();
                this.connectedDevice = null;
                this.writeCharacteristic = null;
                if (this.deviceDisconnectListener) {
                    this.deviceDisconnectListener.remove();
                    this.deviceDisconnectListener = null;
                }
                this.updateConnectionState(ConnectionState.DISCONNECTED);
            } catch (error) {
                console.error('断开连接失败:', error);
                throw error;
            }
        }
    }

    isConnected(): boolean {
        return this.connectionState === ConnectionState.CONNECTED;
    }

    getConnectionState(): ConnectionState {
        return this.connectionState;
    }

    getIsScanning(): boolean {
        return this.isScanning;
    }

    destroy(): void {
        this.stopScan();
        if (this.stateSubscription) {
            this.stateSubscription.remove();
            this.stateSubscription = null;
        }
        if (this.deviceDisconnectListener) {
            this.deviceDisconnectListener.remove();
            this.deviceDisconnectListener = null;
        }
        this.disconnect();
        this.connectionStateListeners = [];
        this.manager.destroy();
        this.initialized = false;
        this.writeCharacteristic = null;
    }
}

export default BluetoothManager.getInstance();