package com.narutohuo.xindazhou.ble.util

import com.narutohuo.xindazhou.ble.config.BLEConstants
import com.narutohuo.xindazhou.ble.model.BLECommand
import com.narutohuo.xindazhou.ble.model.BLEEncryptedData
import java.util.TimeZone
import kotlin.experimental.xor

/**
 * BLE数据包构建器
 * 
 * 负责构建符合新大洲本田蓝牙协议的数据包
 * 按照协议文档"数据下行"结构构建（不包含包头包尾，因为分包协议会处理）
 * 
 * 数据包结构：
 * 地址 + 协议版本 + 时区 + 加密标志 + 操作系统 + 数据长度 + 数据加密区 + 校验
 * 
 * 数据加密区结构（加密前）：
 * 时间戳（4字节）+ 功能码（1字节）+ 指令类型（1字节）+ 应用数据
 */
class BLEPacketBuilder {
    
    /**
     * 构建完整指令数据包（不包含包头包尾）
     * 
     * @param command BLE指令
     * @param encryptKey 加密密钥（16字节），如果为null则不加密
     * @return 完整的数据包（ByteArray），不包含包头包尾
     */
    fun buildPacket(command: BLECommand, encryptKey: ByteArray? = null): ByteArray {
        // 1. 构建数据加密区（时间戳+功能码+指令类型+应用数据）
        val timestamp = System.currentTimeMillis() / 1000 // 秒级时间戳
        val encryptedData = BLEEncryptedData(
            timestamp = timestamp,
            functionCode = command.functionCode,
            instructionType = command.instructionType,
            applicationData = command.applicationData
        )
        
        // 2. 序列化数据加密区
        val encryptedDataBytes = serializeEncryptedData(encryptedData)
        
        // 3. 加密数据（如果提供了密钥）
        val finalDataBytes = if (encryptKey != null) {
            BLECrypto.encrypt(encryptedDataBytes, encryptKey)
        } else {
            encryptedDataBytes
        }
        
        // 4. 构建完整数据包（不包含包头包尾）
        val packet = mutableListOf<Byte>()
        
        // 地址（默认中控地址）
        packet.add(BLEConstants.ADDRESS_CONTROLLER)
        
        // 协议版本
        packet.add(BLEConstants.PROTOCOL_VERSION)
        
        // 时区
        val timezone = (TimeZone.getDefault().rawOffset / (1000 * 60 * 60)).toByte()
        packet.add(timezone)
        
        // 加密标志
        packet.add(if (encryptKey != null) BLEConstants.ENCRYPT_FLAG_ENCRYPTED else BLEConstants.ENCRYPT_FLAG_NONE)
        
        // 操作系统
        packet.add(BLEConstants.OS_ANDROID)
        
        // 数据长度（2字节，大端序）
        val dataLength = finalDataBytes.size
        packet.add((dataLength shr 8).toByte())
        packet.add((dataLength and 0xFF).toByte())
        
        // 数据加密区
        packet.addAll(finalDataBytes.toList())
        
        // 校验（异或校验，从地址到数据区结束）
        val checksum = calculateChecksum(packet)
        packet.add(checksum)
        
        return packet.toByteArray()
    }
    
    /**
     * 构建完整指令数据包（包含包头包尾）
     * 
     * @param command BLE指令
     * @param encryptKey 加密密钥（16字节），如果为null则不加密
     * @return 完整的数据包（ByteArray），包含包头包尾
     */
    fun buildFullPacket(command: BLECommand, encryptKey: ByteArray? = null): ByteArray {
        val packet = buildPacket(command, encryptKey)
        
        // 添加包头和包尾
        val fullPacket = mutableListOf<Byte>()
        fullPacket.add(BLEConstants.PACKET_HEAD)  // 包头
        fullPacket.addAll(packet.toList())
        fullPacket.add(BLEConstants.PACKET_TAIL)  // 包尾
        
        return fullPacket.toByteArray()
    }
    
    /**
     * 构建原始数据包（直接使用传入的数据，不构建数据加密区）
     * 
     * 用于握手等JSON协议场景
     * 
     * @param rawData 原始数据（JSON字节等）
     * @param address 地址（默认0x05中控地址）
     * @param encryptKey 加密密钥（16字节），如果为null则不加密
     * @return 完整的数据包（ByteArray），不包含包头包尾
     */
    fun buildRawPacket(
        rawData: ByteArray,
        address: Byte = BLEConstants.ADDRESS_CONTROLLER,
        encryptKey: ByteArray? = null
    ): ByteArray {
        // 加密数据（如果提供了密钥）
        val finalDataBytes = if (encryptKey != null) {
            BLECrypto.encrypt(rawData, encryptKey)
        } else {
            rawData
        }
        
        // 构建数据包
        val packet = mutableListOf<Byte>()
        
        // 地址
        packet.add(address)
        
        // 协议版本
        packet.add(BLEConstants.PROTOCOL_VERSION)
        
        // 时区
        val timezone = (TimeZone.getDefault().rawOffset / (1000 * 60 * 60)).toByte()
        packet.add(timezone)
        
        // 加密标志
        packet.add(if (encryptKey != null) BLEConstants.ENCRYPT_FLAG_ENCRYPTED else BLEConstants.ENCRYPT_FLAG_NONE)
        
        // 操作系统
        packet.add(BLEConstants.OS_ANDROID)
        
        // 数据长度（2字节，大端序）
        val dataLength = finalDataBytes.size
        packet.add((dataLength shr 8).toByte())
        packet.add((dataLength and 0xFF).toByte())
        
        // 数据区
        packet.addAll(finalDataBytes.toList())
        
        // 校验（异或校验，从地址到数据区结束）
        val checksum = calculateChecksum(packet)
        packet.add(checksum)
        
        return packet.toByteArray()
    }
    
    /**
     * 序列化数据加密区
     * 按照协议：时间戳（4字节）+ 功能码（1字节）+ 指令类型（1字节）+ 应用数据
     */
    private fun serializeEncryptedData(data: BLEEncryptedData): ByteArray {
        val result = mutableListOf<Byte>()
        
        // 时间戳（4字节，大端序）
        val timestamp = data.timestamp.toInt()
        result.add((timestamp shr 24).toByte())
        result.add(((timestamp shr 16) and 0xFF).toByte())
        result.add(((timestamp shr 8) and 0xFF).toByte())
        result.add((timestamp and 0xFF).toByte())
        
        // 功能码
        result.add(data.functionCode)
        
        // 指令类型
        result.add(data.instructionType)
        
        // 应用数据
        result.addAll(data.applicationData.toList())
        
        return result.toByteArray()
    }
    
    /**
     * 计算异或校验
     * 从地址开始（跳过包头），到校验位前一位
     */
    private fun calculateChecksum(packet: List<Byte>): Byte {
        var checksum: Byte = 0x00
        for (i in packet.indices) {
            checksum = checksum.xor(packet[i])
        }
        return checksum
    }
}

