package com.narutohuo.xindazhou.ble.impl

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import com.narutohuo.xindazhou.ble.api.BLEService
import com.narutohuo.xindazhou.ble.callback.*
import com.narutohuo.xindazhou.ble.config.BLEConstants
import com.narutohuo.xindazhou.ble.model.*
import com.narutohuo.xindazhou.ble.util.*
import com.narutohuo.xindazhou.core.log.ILog
import org.json.JSONObject
import java.util.TimeZone
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap
import kotlin.random.Random

/**
 * BLE服务实现类（单例模式）
 * 
 * 封装新大洲本田蓝牙协议，提供高级API供业务模块调用
 */
class BLEServiceImpl private constructor(
    private val context: android.content.Context
) : BLEService {
    
    companion object {
        @Volatile
        private var INSTANCE: BLEServiceImpl? = null
        
        /**
         * 获取BLE服务单例
         */
        @JvmStatic
        fun getInstance(context: android.content.Context? = null): BLEServiceImpl {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: run {
                    if (context == null) {
                        throw IllegalStateException("Context is required for first initialization")
                    }
                    BLEServiceImpl(context.applicationContext).also { INSTANCE = it }
                }
            }
        }
        
        /**
         * 销毁单例
         */
        @JvmStatic
        fun destroyInstance() {
            INSTANCE?.disconnect()
            INSTANCE = null
        }
    }
    
    private val tag = "BLEService"
    
    // 核心组件
    private var scanner: BleScanner? = null
    private var connector: BleConnector? = null
    private var packetSender: BlePacketSender? = null
    private val packetBuilder = BLEPacketBuilder()
    private val packetParser = BLEPacketParser()
    private val packetSplitter = BLEPacketSplitter()
    
    // 状态
    private var currentDevice: BLEDevice? = null
    private var encryptKey: ByteArray? = null
    private var dataReceivedListener: DataCallback? = null
    private var pendingUserId: ByteArray? = null
    private var pendingUserType: Byte? = null
    private var connectionCallback: ((BLEResponse) -> Unit)? = null
    
    // 连接状态监听
    private var connectionListener: ConnectionListener? = null
    
    // 回调映射（用于处理异步响应）
    private val responseCallbacks = ConcurrentHashMap<String, (BLEResponse) -> Unit>()
    
    /**
     * 连接状态监听器
     */
    private data class ConnectionListener(
        val onConnected: () -> Unit,
        val onDisconnected: () -> Unit,
        val onError: (String) -> Unit
    )
    
    override fun startScan(callback: (BLEDevice) -> Unit) {
        scanner = BleScanner(
            context = context,
            onDeviceFound = { device ->
                    val bleDevice = BLEDevice(
                    name = device.name,
                        address = device.address,
                    rssi = 0 // RSSI 在扫描结果中获取
                    )
                callback(bleDevice)
            },
            onScanFinished = {
                ILog.d(tag, "扫描完成")
            },
            filterDeviceName = BLEConstants.TARGET_DEVICE_NAME,
            filterDeviceAddress = BLEConstants.TARGET_DEVICE_ADDRESS
        )
        scanner?.startScan()
    }
    
    override fun stopScan() {
        scanner?.stopScan()
        scanner = null
    }
    
    override fun connect(device: BLEDevice, userId: ByteArray, userType: Byte, callback: (BLEResponse) -> Unit) {
        ILog.d(tag, "========== 开始连接流程 ==========")
        ILog.d(tag, "设备名称: ${device.name}")
        ILog.d(tag, "设备地址: ${device.address}")
        ILog.d(tag, "用户类型: $userType")
        ILog.d(tag, "用户ID长度: ${userId.size}")
        ILog.d(tag, "====================================")
        
        // 保存用户信息和回调
        pendingUserId = userId
        pendingUserType = userType
        connectionCallback = callback
        
        currentDevice = device
        
        // 生成加密密钥（基于MAC地址）
        val macBytes = device.address.replace(":", "").hexToByteArray()
        encryptKey = BLECrypto.generateAESKey(macBytes)
        ILog.d(tag, "加密密钥已生成")
        
        val adapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter()
        if (adapter == null) {
            ILog.e(tag, "❌ BluetoothAdapter 为 null")
            callback(BLEResponse(success = false, errorMessage = "蓝牙适配器未初始化"))
            return
        }
        
        if (!adapter.isEnabled) {
            ILog.e(tag, "❌ 蓝牙未开启")
            callback(BLEResponse(success = false, errorMessage = "蓝牙未开启"))
            return
        }
        
        ILog.d(tag, "✅ 蓝牙适配器状态正常")
        
        val androidDevice = try {
            adapter.getRemoteDevice(device.address)
        } catch (e: IllegalArgumentException) {
            ILog.e(tag, "❌ 无效的设备地址: ${device.address}", e)
            callback(BLEResponse(success = false, errorMessage = "无效的设备地址: ${device.address}"))
            return
        }
        
        ILog.d(tag, "✅ 获取到 BluetoothDevice 对象")
        
        connector = BleConnector(
            context = context,
            device = androidDevice,
            onConnected = { gatt, writeChar ->
                // 创建数据包发送器
                packetSender = BlePacketSender(
                    gatt = gatt,
                    writeChar = writeChar,
                    splitter = packetSplitter,
                    onPairing = { pairing ->
                        ILog.d(tag, "收到配对请求，状态: $pairing")
                    },
                    onHandshakeRequest = { random ->
                        // 收到设备的握手请求，发送握手应答
                        handleHandshakeResponse(random, userId, userType)
                    }
                )
                
                // 设置业务消息监听
                packetSender?.setBusinessMessageListener { title, message, extras, id ->
                    dataReceivedListener?.onDataReceived(message.toByteArray())
                }
                
                // 注入到连接器
                connector?.packetSender = packetSender
                
                ILog.d(tag, "GATT连接成功，开始握手")
                // 连接成功后自动进行握手
                performHandshake(userId, userType)
                
                // 通知连接状态监听器
                connectionListener?.onConnected()
            },
            onDisconnected = {
                ILog.d(tag, "连接断开")
                currentDevice = null
                encryptKey = null
                packetSender = null
                connector = null
                connectionCallback?.invoke(BLEResponse(success = false, errorMessage = "连接已断开"))
                connectionCallback = null
                pendingUserId = null
                pendingUserType = null
                
                // 通知连接状态监听器
                connectionListener?.onDisconnected()
            },
            onError = { error ->
                ILog.e(tag, "连接失败: $error")
                connectionCallback?.invoke(BLEResponse(success = false, errorMessage = error))
                connectionCallback = null
                pendingUserId = null
                pendingUserType = null
                
                // 通知连接状态监听器
                connectionListener?.onError(error)
            }
        )
        
        ILog.d(tag, "✅ BleConnector 已创建，开始连接...")
        connector?.connect()
    }
    
    override fun disconnect() {
        connector?.disconnect()
        scanner?.stopScan()
        currentDevice = null
        encryptKey = null
        packetSender = null
        connector = null
        scanner = null
        pendingUserId = null
        pendingUserType = null
        connectionCallback = null
    }
    
    override fun isConnected(): Boolean {
        return currentDevice != null && packetSender != null
    }
    
    override fun initializeAndConnect(
        userId: ByteArray,
        userType: Byte,
        onConnected: () -> Unit,
        onDisconnected: (() -> Unit)?,
        onDataReceived: ((ByteArray) -> Unit)?,
        onError: ((String) -> Unit)?,
        scanTimeoutMs: Long
    ) {
        // 设置连接状态监听
        setConnectionListener(
            onConnected = onConnected,
            onDisconnected = onDisconnected ?: {},
            onError = onError ?: { ILog.e(tag, it) }
        )
        
        // 设置数据接收监听
        if (onDataReceived != null) {
            setDataReceivedListener(object : DataCallback {
                override fun onDataReceived(data: ByteArray) {
                    onDataReceived(data)
                }
            })
        }
        
        // 扫描并连接
        scanAndConnect(
            userId = userId,
            userType = userType,
            scanTimeoutMs = scanTimeoutMs,
            onScanning = null,
            onDeviceFound = null,
            onConnected = onConnected,
            onError = { error -> onError?.invoke(error) ?: ILog.e(tag, error) }
        )
    }
    
    override fun scanAndConnect(
        userId: ByteArray,
        userType: Byte,
        scanTimeoutMs: Long,
        onScanning: (() -> Unit)?,
        onDeviceFound: ((BLEDevice) -> Unit)?,
        onConnected: () -> Unit,
        onError: (String) -> Unit
    ) {
        // 开始扫描
        onScanning?.invoke()
        
        var foundDevice: BLEDevice? = null
        var scanTimeoutHandler: android.os.Handler? = null
        
        startScan { device ->
            // 找到设备，停止扫描
            stopScan()
            scanTimeoutHandler?.removeCallbacksAndMessages(null)
            
            foundDevice = device
            onDeviceFound?.invoke(device)
            
            // 连接设备
            connect(device, userId, userType) { response ->
                if (response.success) {
                    onConnected()
                } else {
                    onError("连接失败: ${response.errorMessage}")
            }
            }
        }
        
        // 设置超时
        scanTimeoutHandler = android.os.Handler(android.os.Looper.getMainLooper())
        scanTimeoutHandler.postDelayed({
            if (foundDevice == null) {
                stopScan()
                onError("扫描超时，未找到设备")
            }
        }, scanTimeoutMs)
        }
    
    override fun setConnectionListener(
        onConnected: () -> Unit,
        onDisconnected: () -> Unit,
        onError: (String) -> Unit
    ) {
        this.connectionListener = ConnectionListener(
            onConnected = onConnected,
            onDisconnected = onDisconnected,
            onError = onError
        )
    }
    
    /**
     * 处理握手响应（收到设备的握手请求后调用）
     */
    private fun handleHandshakeResponse(random: Int, userId: ByteArray, userType: Byte) {
        if (!isConnected() || packetSender == null || encryptKey == null) {
            ILog.e(tag, "无法发送握手应答：未连接或密钥未生成")
            return
        }
        
        try {
            // 将 random 转为偶数位十六进制字符串
            val randomHex = random.toEvenHex()
            ILog.d(tag, "握手随机数（十六进制）: $randomHex")
            
            // 将十六进制字符串转为 ByteArray
            val randomBytes = randomHex.hexToByteArray()
            
            // 使用 AES 加密随机数
            val encryptedRandomBytes = BLECrypto.encrypt(randomBytes, encryptKey!!)
            
            // 将加密后的 ByteArray 转为十六进制字符串
            val encryptedRandomHex = encryptedRandomBytes.toHexString()
            ILog.d(tag, "加密后的随机数（十六进制）: $encryptedRandomHex")
            
            // 构建握手应答 JSON
            val json = JSONObject().apply {
                put("TY", 3)  // 类型：握手
                put("IN", 3)  // 指令：握手应答
                put("ID", UUID.randomUUID().toString())
                put("TS", System.currentTimeMillis())
                put("C", JSONObject().apply {
                    put("D", JSONObject().apply {
                        put("EncryptedRandom", encryptedRandomHex)
                        put("UserType", userType.toInt())
                        put("UserID", userId.toHexString())
                    })
                })
            }
            
            ILog.d(tag, "发送握手应答")
            
            // 发送握手应答（不等待回调，因为这是响应，不是请求）
            sendRawData(json.toString().toByteArray(Charsets.UTF_8)) { response ->
                if (response.success) {
                    ILog.d(tag, "握手应答发送成功")
                } else {
                    ILog.e(tag, "握手应答发送失败: ${response.errorMessage}")
                }
            }
            
        } catch (e: Exception) {
            ILog.e(tag, "处理握手响应失败", e)
        }
    }
    
    /**
     * 执行握手（内部方法，连接成功后自动调用）
     */
    private fun performHandshake(userId: ByteArray, userType: Byte) {
        if (!isConnected()) {
            connectionCallback?.invoke(BLEResponse(success = false, errorMessage = "未连接设备"))
            connectionCallback = null
            return
        }
        
        try {
            // 构建握手JSON
            val json = JSONObject().apply {
                put("TY", 3)  // 类型：握手
                put("IN", 3)  // 指令：握手请求
                put("C", JSONObject().apply {
                    put("D", JSONObject().apply {
                        put("Random", Random.nextInt(0xFFFF))
                        put("UserID", userId.toHexString())
                        put("UserType", userType.toInt())
                    })
                })
            }
            
            ILog.d(tag, "开始握手认证")
            
            // 发送握手请求
            sendRawData(json.toString().toByteArray(Charsets.UTF_8)) { response ->
                if (response.success) {
                    ILog.d(tag, "握手成功，连接完成")
                    // 握手成功，通知业务层连接完成
                    connectionCallback?.invoke(BLEResponse(success = true))
                    connectionCallback = null
                    pendingUserId = null
                    pendingUserType = null
            } else {
                    ILog.e(tag, "握手失败: ${response.errorMessage}")
                    // 握手失败，断开连接
                    disconnect()
                    connectionCallback?.invoke(BLEResponse(success = false, errorMessage = "握手失败: ${response.errorMessage}"))
                    connectionCallback = null
                    pendingUserId = null
                    pendingUserType = null
                }
            }
        } catch (e: Exception) {
            ILog.e(tag, "握手失败", e)
            disconnect()
            connectionCallback?.invoke(BLEResponse(success = false, errorMessage = "握手失败: ${e.message}"))
            connectionCallback = null
            pendingUserId = null
            pendingUserType = null
        }
    }
    
    override fun sendCommand(command: BLECommand, callback: (BLEResponse) -> Unit) {
        if (!isConnected()) {
            callback(BLEResponse(success = false, errorMessage = "未连接设备"))
            return
        }
        
        try {
            // 使用 BLEPacketBuilder 构建完整指令数据包
            val packetData = packetBuilder.buildPacket(
                command = command,
                encryptKey = encryptKey
            )
            
            // 发送数据
            sendRawData(packetData) { response ->
                callback(response)
            }
        } catch (e: Exception) {
            ILog.e(tag, "发送指令失败", e)
            callback(BLEResponse(success = false, errorMessage = "发送指令失败: ${e.message}"))
        }
    }
    
    override fun sendAppControlCommand(instructionType: Byte, data: ByteArray, callback: (BLEResponse) -> Unit) {
        val command = BLECommand(
            functionCode = BLEConstants.FUNCTION_CODE_APP_CONTROL,
            instructionType = instructionType,
            applicationData = data
        )
        sendCommand(command, callback)
    }
    
    override fun sendSystemControlCommand(instructionType: Byte, data: ByteArray, callback: (BLEResponse) -> Unit) {
        val command = BLECommand(
            functionCode = BLEConstants.FUNCTION_CODE_SYSTEM_CONTROL,
            instructionType = instructionType,
            applicationData = data
        )
        sendCommand(command, callback)
    }
    
    override fun queryVehicleInfo(callback: (BLEResponse) -> Unit) {
        val command = BLECommand(
            functionCode = BLEConstants.FUNCTION_CODE_SYSTEM_QUERY,
            instructionType = 0x01,  // 查询车辆信息
            applicationData = ByteArray(0)
        )
        sendCommand(command, callback)
    }
    
    // ========== 便捷方法实现 ==========
    
    override fun setDefense(enabled: Boolean, callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.SET_DEFENSE,
            byteArrayOf(if (enabled) 0x01 else 0x00),
            callback
        )
    }
    
    override fun powerOn(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.POWER_ON_OFF,
            byteArrayOf(0x01),
            callback
        )
    }
    
    override fun powerOff(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.POWER_ON_OFF,
            byteArrayOf(0x00),
            callback
        )
    }
    
    override fun findCar(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.FIND_CAR,
            byteArrayOf(0x01),
            callback
        )
    }
    
    override fun unlockSeat(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.SEAT_LOCK,
            byteArrayOf(0x01),
            callback
        )
    }
    
    override fun unlockHandlebar(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.HANDLEBAR_LOCK,
            byteArrayOf(0x01),
            callback
        )
    }
    
    override fun lockHandlebar(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.HANDLEBAR_LOCK,
            byteArrayOf(0x00),
            callback
        )
    }
    
    override fun unlockTrunk(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.TRUNK_LOCK,
            byteArrayOf(0x01),
            callback
        )
    }
    
    override fun lockTrunk(callback: (BLEResponse) -> Unit) {
        sendAppControlCommand(
            AppControlInstruction.TRUNK_LOCK,
            byteArrayOf(0x00),
            callback
        )
    }
    
    override fun setSensorUnlock(enabled: Boolean, callback: (BLEResponse) -> Unit) {
        sendSystemControlCommand(
            SystemControlInstruction.SENSOR_UNLOCK,
            byteArrayOf(if (enabled) 0x01 else 0x00),
            callback
        )
    }
    
    override fun setAmbientLight(enabled: Boolean, callback: (BLEResponse) -> Unit) {
        sendSystemControlCommand(
            SystemControlInstruction.AMBIENT_LIGHT,
            byteArrayOf(if (enabled) 0x01 else 0x00),
            callback
        )
    }
    
    override fun setAmbientLightColor(r: Int, g: Int, b: Int, callback: (BLEResponse) -> Unit) {
        sendSystemControlCommand(
            SystemControlInstruction.AMBIENT_LIGHT_COLOR,
            byteArrayOf(
                r.coerceIn(0, 255).toByte(),
                g.coerceIn(0, 255).toByte(),
                b.coerceIn(0, 255).toByte()
            ),
            callback
        )
    }
    
    override fun setAutoPowerOffTime(timeSeconds: Int, callback: (BLEResponse) -> Unit) {
        val time = timeSeconds.coerceIn(0, 60000)
        val data = java.nio.ByteBuffer.allocate(2)
            .order(java.nio.ByteOrder.LITTLE_ENDIAN)
            .putShort(time.toShort())
            .array()
        
        sendSystemControlCommand(
            SystemControlInstruction.AUTO_POWER_OFF_TIME,
            data,
            callback
        )
    }
    
    override fun setSpeakerVolume(volume: Int, callback: (BLEResponse) -> Unit) {
        val vol = volume.coerceIn(0, 100)
        sendSystemControlCommand(
            SystemControlInstruction.SPEAKER_VOLUME,
            byteArrayOf(vol.toByte()),
            callback
        )
    }
    
    override fun setDataReceivedListener(listener: DataCallback) {
        this.dataReceivedListener = listener
    }
    
    override fun writeRawData(data: ByteArray, callback: (BLEResponse) -> Unit) {
        sendRawData(data, callback)
    }
    
    /**
     * 发送原始数据（内部方法）
     */
    private fun sendRawData(data: ByteArray, callback: (BLEResponse) -> Unit) {
        if (!isConnected() || packetSender == null) {
            callback(BLEResponse(success = false, errorMessage = "未连接设备"))
            return
        }
        
        try {
            // 生成业务ID
            val businessId = packetSender!!.generateBusinessId()
            
            // 注册回调（使用业务ID作为key）
            val callbackKey = businessId.toHexString()
            responseCallbacks[callbackKey] = callback
            
            // 发送数据（会自动分包）
            packetSender!!.enqueueAndStart(
                rawData = data,
                businessId = businessId,
                isRequest = true
            )
            
            // 注意：实际响应会在 onCharacteristicNotify 中处理
            // 这里暂时直接返回成功（实际应该等待响应）
            // TODO: 实现响应等待机制
            
        } catch (e: Exception) {
            ILog.e(tag, "发送数据失败", e)
            callback(BLEResponse(success = false, errorMessage = "发送失败: ${e.message}"))
        }
    }
    
}
