#include "BluetoothClient.h"
#include <QDebug>
#include <QBluetoothLocalDevice>
#include <QDBusInterface>
#include <QLowEnergyConnectionParameters>
#include <QProcess>
#include <QDBusPendingReply>

void releaseBluetoothResource() {
    qDebug() << "[BLE] 释放系统蓝牙资源...";
    system("sudo killall bluetoothctl 2>/dev/null");
    system("sudo systemctl stop bluetooth");
    system("sudo hciconfig hci0 down");
    QThread::msleep(2000);
    system("sudo hciconfig hci0 up");
    system("sudo systemctl start bluetooth");
    QThread::msleep(1000); // 等待服务启动
}

BLEClient::BLEClient(QObject *parent) : QThread(parent)
{
//    releaseBluetoothResource();

    // 初始化扫描代理
    m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
    m_discoveryAgent->setLowEnergyDiscoveryTimeout(0);

    // 连接扫描信号
    connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BLEClient::onDeviceDiscovered);
    connect(m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &BLEClient::onDiscoveryFinished);
    connect(m_discoveryAgent, QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(&QBluetoothDeviceDiscoveryAgent::error), this, &BLEClient::onDiscoveryError);

    // 初始化多包接收
    m_multiPackRecvState.timeoutTimer.setSingleShot(true);
    m_multiPackRecvState.timeoutTimer.setInterval(500);
    connect(&m_multiPackRecvState.timeoutTimer, &QTimer::timeout, this, [=]() {
        getWorkTicketOtherData();
    });
    resetMultiPackRecvState();

    // 初始化工作票下发多包状态
    m_workTicketSendState.packTimeoutTimer.setSingleShot(true);
    m_workTicketSendState.packTimeoutTimer.setInterval(1000);
    connect(&m_workTicketSendState.packTimeoutTimer, &QTimer::timeout, this, [=]() {
       sendNextWorkTicketPack();
    });
    resetWorkTicketSendState();
}

BLEClient::~BLEClient()
{
    stopThreadAndRelease();

    disconnectDevice();
    delete m_discoveryAgent;
    if (m_leController) {
        delete m_leController;
    }
    if (m_targetService) {
        delete m_targetService;
    }
}

void BLEClient::startDeviceDiscovery()
{
//    QMutexLocker locker(&m_mutex);

    // 前置校验：避免重复启动/代理为空
    if (m_isSearching || !m_discoveryAgent) {
        if (m_isSearching) {
            qInfo() << "[BLE] 蓝牙搜索已在运行，无需重复启动";
        }
        else {
            emit discoveryError("蓝牙搜索代理未初始化");
        }
        return;
    }

    // 检查蓝牙适配器是否可用
    if (QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods() == 0) {
        QString errMsg = "无可用的蓝牙适配器（蓝牙未开启/无硬件）";
        qCritical() << "[BLE] " << errMsg;
        emit discoveryError(errMsg);
        return;
    }

    // 启动低功耗蓝牙搜索
    qInfo() << "[BLE] 开始搜索BLE设备..." << m_selectedMAC;
    m_isSearching = true;
    emit discoveryStateChanged(true);

    m_discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
}

void BLEClient::stopDeviceDiscovery()
{
    QMutexLocker locker(&m_mutex);
    if (!m_isSearching || !m_discoveryAgent) return;

    qInfo() << "[BLE] 停止蓝牙搜索";
    m_discoveryAgent->stop();
    m_isSearching = false;
    emit discoveryStateChanged(false);
}

void BLEClient::onDeviceDiscovered(const QBluetoothDeviceInfo& device)
{
    if (device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) {
        QString mac = device.address().toString();
        if (!m_selectedMAC.isEmpty() && mac == m_selectedMAC) {
            qInfo() << "[BLE] 发现目标设备：" << device.name() << "，MAC：" << mac;
            QTimer::singleShot(200, this, [=]() {
               connectDevice(mac, "keyLock");
           });
            m_discoveryAgent->stop();
            m_isSearching = false;
        }
    }
}

void BLEClient::onDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error error)
{
    QString errMsg;
    switch (error) {
        case QBluetoothDeviceDiscoveryAgent::PoweredOffError:
            errMsg = "蓝牙适配器未开启";
            break;
        case QBluetoothDeviceDiscoveryAgent::InputOutputError:
            errMsg = "蓝牙IO错误（请检查权限）";
            break;
        case QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError:
            errMsg = "无效的蓝牙适配器";
            break;
        default:
            errMsg = "搜索错误：" + m_discoveryAgent->errorString();
            break;
    }
    qCritical() << "[BLE] " << errMsg;
    emit discoveryError(errMsg);
    m_isSearching = false;
    emit discoveryStateChanged(false);
}

void BLEClient::onDiscoveryFinished()
{
    if (m_isSearching) {
        qInfo() << "[BLE] 搜索意外终止";
        m_isSearching = false;
        emit discoveryStateChanged(false);
    }
}

void BLEClient::connectDevice(const QString& macAddress, const QString& name)
{
    Q_UNUSED(name);
    QMutexLocker locker(&m_mutex);
    if (m_leController && m_leController->state() == QLowEnergyController::UnconnectedState) {
        emit connectStateChanged(QLowEnergyController::UnconnectedState, "当前非断开状态，无法连接");
        return;
    }

    m_targetMac = macAddress;
    QBluetoothAddress addr(macAddress);
    if (addr.isNull()) {
        emit connectStateChanged(QLowEnergyController::UnconnectedState, "无效MAC地址");
        return;
    }

    QString noPairMAC = macAddress;
    noPairMAC = noPairMAC.toLower().replace(":", "_");
    QDBusInterface bluezDeviceIface(
        "org.bluez",
        "/org/bluez/hci0/dev_" + noPairMAC,
        "org.bluez.Device1",
        QDBusConnection::systemBus(),
        this
    );

    QDBusInterface bluezPropsIface(
        "org.bluez",
        "/org/bluez/hci0/dev_" + noPairMAC,
        "org.freedesktop.DBus.Properties",
        QDBusConnection::systemBus(),
        this
    );
    bluezDeviceIface.setTimeout(5000);
    bluezPropsIface.setTimeout(5000);

    if (bluezDeviceIface.isValid()) {
        QVariant trustedValue = QVariant::fromValue(true);
        QDBusPendingCall pendingCall = bluezPropsIface.asyncCall(
                    "Set",
                    "org.bluez.Device1",
                    "Trusted",
                    QVariant::fromValue(QDBusVariant(trustedValue))
                );
        QDBusPendingReply<void> reply = pendingCall;
        reply.waitForFinished(); // 阻塞等待DBus调用完成
        if (reply.isError()) {
            qWarning() << "[BLE] 设置信任属性失败：" << reply.error().message();
        } else {
            qInfo() << "[BLE] 信任属性设置成功";
        }

        // 设置BlueZ设备属性：禁用自动绑定、禁用配对
        bluezPropsIface.call(
            "Set",
            "org.bluez.Device1",
            "AutoConnect",
            QVariant::fromValue(QDBusVariant(false))
        );
        // 设置Bonded=false
        bluezPropsIface.call(
            "Set",
            "org.bluez.Device1",
            "Bonded",
            QVariant::fromValue(QDBusVariant(false))
        );
        // 设置PairingAllowed=false
        bluezPropsIface.call(
            "Set",
            "org.bluez.Device1",
            "PairingAllowed",
            QVariant::fromValue(QDBusVariant(false))
        );
        // 设置Blocked=false
        bluezPropsIface.call(
            "Set",
            "org.bluez.Device1",
            "Blocked",
            QVariant::fromValue(QDBusVariant(false))
        );

        bluezDeviceIface.call("CancelPairing");
        bluezDeviceIface.call("Disconnect");
//        bluezDeviceIface.setProperty("AutoConnect", false);    // 禁用自动连接
//        bluezDeviceIface.setProperty("Bonded", false);         // 取消绑定
//        bluezDeviceIface.setProperty("Trusted", true);         // 信任设备
//        bluezDeviceIface.setProperty("PairingAllowed", false); // 禁用配对
//        bluezDeviceIface.setProperty("Blocked", false);        // 确保设备未被拉黑
//        bluezDeviceIface.call("CancelPairing");                // 取消待处理配对
//        bluezDeviceIface.call("SetPairingMode", false);
//        // 移除已有绑定（若存在）
//        bluezDeviceIface.call("Disconnect");
//        bluezDeviceIface.call("Remove");
        QDBusPendingReply<QVariant> getReply = bluezPropsIface.asyncCall(
           "Get",
           "org.bluez.Device1",
           "Trusted"
       );
       getReply.waitForFinished();
       if (getReply.isError()) {
           qWarning() << "[BLE] 获取信任属性失败：" << getReply.error().message();
       } else {
           bool isTrusted = getReply.value().toBool();
           if (isTrusted) {
               qInfo() << "[BLE] 设备信任状态验证通过（Trusted=true）";
           } else {
               qWarning() << "[BLE] 设备信任状态验证失败（Trusted=false）";
           }
       }

       // 5. 等待BlueZ缓存同步（关键：1秒）
       QThread::msleep(1000);
        qDebug() << "[BLE] DBus禁用绑定成功：" << "/org/bluez/hci0/dev_" + noPairMAC;

        QThread::msleep(500);
    }
    else {
        qDebug() << "[BLE] 暂未扫描到设备，连接时再禁用绑定";
    }

    // 释放旧控制器
    if (m_leController) {
        m_leController->disconnectFromDevice();
        m_leController = nullptr;
    }
    if (m_targetService) {
//        delete m_targetService;
        m_targetService = nullptr;
    }

    // 初始化蓝牙适配器
    QBluetoothLocalDevice localDev;
    if (localDev.hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
        localDev.powerOn();
    }

    // 初始化QLowEnergyController
    m_leController = QLowEnergyController::createCentral(addr, localDev.address(), this);

    if (!m_leController) {
        qDebug() << "[BLEClient::connectDevice]: 创建蓝牙控制器失败";
        emit connectStateChanged(QLowEnergyController::UnconnectedState, "创建蓝牙控制器失败");
        return;
    }
//    m_leController->setRemoteAddressType(QLowEnergyController::RandomAddress);
    m_leController->setRemoteAddressType(QLowEnergyController::PublicAddress);

    // 缩短连接超时、调整间隔，避免协商卡住
//    QLowEnergyConnectionParameters params;
//    params.setIntervalRange(6, 12); // 最小连接间隔（7.5ms*6=45ms）最大连接间隔（7.5ms*12=90ms
//    params.setSupervisionTimeout(500); // 监督超时（500ms，默认2000ms太长）
//    m_leController->requestConnectionUpdate(params);

    connect(m_leController, &QLowEnergyController::stateChanged, this, &BLEClient::onControllerStateChanged);
    connect(m_leController, &QLowEnergyController::serviceDiscovered, this, &BLEClient::onServiceDiscovered);
    connect(m_leController, &QLowEnergyController::discoveryFinished, this, []() {
        qInfo() << "[BLE] 服务发现流程全部完成";
    });
    connect(m_leController, &QLowEnergyController::disconnected, this, [this]() {
        emit connectStateChanged(QLowEnergyController::UnconnectedState, "蓝牙已断开");
    });
    connect(m_leController, QOverload<QLowEnergyController::Error>::of(&QLowEnergyController::error),
                this, [this](QLowEnergyController::Error error) {
                    QString errMsg = QString("错误码：%1，描述：%2")
                                         .arg(error)
                                         .arg(m_leController->errorString());
                    qWarning() << "[BLE] 控制器错误：" << errMsg;
//                    releaseBluetoothResource();
                    disconnectDevice();
                    msleep(3000);
                    emit signalFailConnect();
                    emit connectStateChanged(QLowEnergyController::UnconnectedState, errMsg);
                });

    emit connectStateChanged(m_leController->state(), "正在连接...");
    m_leController->connectToDevice();
}

void BLEClient::disconnectDevice()
{
//    QMutexLocker locker(&m_mutex);
    if (m_leController && m_leController->state() == QLowEnergyController::UnconnectedState) {
        return;
    }

    emit connectStateChanged(QLowEnergyController::UnconnectedState, "正在断开...");

    // 发送断开指令
    sendDisconnectCmd();

    if (m_leController && m_leController->state() == QLowEnergyController::DiscoveredState) {
        m_leController->disconnectFromDevice();
    }
    else {
        emit connectStateChanged(QLowEnergyController::UnconnectedState, "已断开");
    }
}

void BLEClient::testFunc()
{
    qInfo() << "\n==================== 开始蓝牙业务测试 ====================";
//    connectDevice("CC:BA:97:21:71:CA", "keyLock");

    // 绑定连接状态信号
    connect(this, &BLEClient::tokenReceived, this, [this](const BLEToken& token) {
        Q_UNUSED(token);
        QTimer::singleShot(1000, this, [this]() {
//            // 1. 获取设备状态
//            getDeviceStatus();

//            // 2. 5秒后设置充电参数（开启80%，终止90%）
//            QTimer::singleShot(5000, this, [this]() {
//                setChargeParam(80, 90);
//            });

//            // 3. 10秒后获取电量
//            QTimer::singleShot(10000, this, [this]() {
//                getBatteryStatus();
//            });

//            // 4. 15秒后获取RFID
//            QTimer::singleShot(15000, this, [this]() {
//                getRFID();
//            });

//            // 5. 20秒后切换工作模式
//            QTimer::singleShot(20000, this, [this]() {
//                switchDeviceMode(true);
//            });

                // 6. 25秒后切换获取作业票完成情况
//            QTimer::singleShot(25000, this, [this]() {
//                getWorkTicketResult();
//            });
                // 7. 30秒后切换作业票下发
//                QTimer::singleShot(30000, this, [this]() {
//                    BLERWorkTicket workTicket;
//                    workTicket.ticketData = "{\"cardNo\":\"D2931A25\",\"data\":[{\"codeId\":1,\"dataList\":[{\"dataId\":87,\"equipName\":\"E_29\",\"equipRfidNo\":\"1B9105AF\",\"target\":0},{\"dataId\":88,\"equipName\":\"E_30\",\"equipRfidNo\":\"FB9091E5\",\"target\":0}],\"taskCode\":\"165\"}],\"lockList\":[{\"lockId\":1,\"rfid\":\"C097D395\"},{\"lockId\":2,\"rfid\":\"A04AD495\"}],\"password\":\"123456\"}";
//                    sendWorkTicket(workTicket);
//                });
        });
    });

    // 绑定业务结果信号
    connect(this, &BLEClient::deviceStatusReceived, this, [](const BLEDeviceStatus& status) {
        qInfo() << "[Test] 设备状态：" << (status.success ? status.statusDesc : "获取失败");
    });

    connect(this, &BLEClient::batteryStatusReceived, this, [](quint8 battery, const BLEChargeParam& chargeState) {
        qInfo() << "[Test] 电量：" << battery << "%" << "，充电状态：" << chargeState.chargeStateDesc;
    });

    connect(this, &BLEClient::rfidReceived, this, [](const BLERFIDInfo& rfidInfo) {
        if (rfidInfo.success) {
            qInfo() << "[Test] RFID号：" << rfidInfo.rfidList.join(",");
        } else {
            qInfo() << "[Test] RFID获取失败";
        }
    });

    connect(this, &BLEClient::cmdSendResult, this, [](bool success, const QString& cmdName, const QString& msg) {
        qInfo() << "[Test] " << cmdName << "：" << (success ? "成功" : "失败") << "，描述：" << msg;
    });

    //    startDeviceDiscovery();
}

void BLEClient::stopThreadAndRelease()
{
    m_threadstatus = false;
    wait();
}

void BLEClient::sendJobTicket(const QJsonDocument &doc)
{
//    switchDeviceMode(false);

    BLERWorkTicket workTicket;
    workTicket.ticketDoc = doc;
    sendWorkTicket(workTicket);
    msleep(50);
}

void BLEClient::startGetWorkTicketResult()
{
    msleep(50);
    getWorkTicketResult();
    msleep(50);
}

bool BLEClient::isConnected()
{
    if (m_leController) {
        return m_leController->state() == QLowEnergyController::DiscoveredState;
    }
    else {
        return false;
    }
}

void BLEClient::apiConnectDevice(const QString &macAddress)
{
    m_selectedMAC = macAddress;
    m_discoveryAgent->start();
}

void BLEClient::run()
{
    while (m_threadstatus) {
        if (!m_token.isEmpty()) {
            getDeviceStatus();
        }
        msleep(50);
    }
}

void BLEClient::onControllerStateChanged(QLowEnergyController::ControllerState state)
{
    switch (state) {
        case QLowEnergyController::ConnectedState: {
            qInfo() << "[BLE] 设备连接成功，开始发现服务...";
            emit connectStateChanged(QLowEnergyController::ConnectingState, "连接成功");

            QLowEnergyConnectionParameters params;
            params.setIntervalRange(6, 12); // 7.5ms*6=45ms ~ 7.5ms*12=90ms
            params.setSupervisionTimeout(500); // 500ms
            m_leController->requestConnectionUpdate(params);

            // 发现所有服务
            m_leController->discoverServices();
            break;
        }
        case QLowEnergyController::UnconnectedState:
            emit connectStateChanged(QLowEnergyController::UnconnectedState, "连接断开");
            break;
        case QLowEnergyController::ConnectingState:
            emit connectStateChanged(QLowEnergyController::ConnectingState, "正在连接...");
            break;
        case QLowEnergyController::DiscoveringState:
            qInfo() << "[BLE] 正在发现服务...";
            break;
        default:
            break;
    }
}

void BLEClient::onServiceDiscovered(const QBluetoothUuid& uuid)
{
    // 匹配目标服务UUID（FEE7）
    if (uuid.toUInt16() == BLE_SERVICE_UUID) {
        qInfo() << "[BLE] 发现目标服务：" << QString::number(BLE_SERVICE_UUID, 16);
        // 获取服务对象
        m_targetService = m_leController->createServiceObject(uuid, this);
        if (!m_targetService) {
            qWarning() << "[BLE] 创建服务对象失败";
            return;
        }

        // 连接服务信号
        connect(m_targetService, &QLowEnergyService::stateChanged, this, &BLEClient::onServiceStateChanged);
        connect(m_targetService, &QLowEnergyService::characteristicChanged, this, &BLEClient::onCharacteristicChanged);
        connect(m_targetService, &QLowEnergyService::characteristicWritten, this, &BLEClient::onWriteCharacteristicFinished);

        // 发现服务的特征值
        m_targetService->discoverDetails();
    }
}

void BLEClient::onServiceStateChanged(QLowEnergyService::ServiceState state)
{
    if (state != QLowEnergyService::ServiceDiscovered) return;

    qInfo() << "[BLE] 服务特征值发现完成";
    // 获取所有特征值
    QList<QLowEnergyCharacteristic> chars = m_targetService->characteristics();
    for (const auto& chara : chars) {
        quint16 charUuid = chara.uuid().toUInt16();
        if (charUuid == BLE_CHAR_INDICATE_UUID) {
            m_indicateChar = chara;

           bool supportNotify = (m_indicateChar.properties() & QLowEnergyCharacteristic::Notify);
           bool supportIndicate = (m_indicateChar.properties() & QLowEnergyCharacteristic::Indicate);
           if (!supportNotify && !supportIndicate) {
               qDebug() << "[BLE] 特征值" << QString::number(charUuid,16) << "不支持Notify/Indicate，无法接收消息";
               return;
           }
            // 启用通知
            QLowEnergyDescriptor desc = chara.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
            if (desc.isValid()) {
                QByteArray enableData;
                if (supportIndicate) {
                    enableData = QByteArray::fromHex("0200"); // 开启Indicate
                    qInfo() << "[BLE] 开启Indicate特征值：" << QString::number(charUuid,16);
                }
                else {
                    enableData = QByteArray::fromHex("0100"); // 开启Notify
                    qInfo() << "[BLE] 开启Notify特征值：" << QString::number(charUuid,16);
                }
                m_targetService->writeDescriptor(desc, enableData);
            }
        }
        else if (charUuid == BLE_CHAR_WRITE_UUID) {
            m_writeChar = chara;
            qInfo() << "[BLE] 绑定写特征值：" << QString::number(BLE_CHAR_WRITE_UUID, 16);
        }
    }

    // 特征值绑定完成后，自动获取令牌
    if (m_indicateChar.isValid() && m_writeChar.isValid()) {
        qInfo() << "[BLE] 特征值绑定完成，开始获取令牌...";
        getToken();
    }
}

QByteArray BLEClient::buildDownFrame(quint8 ins, const QByteArray& data, const QByteArray& token)
{
    // 下行指令结构：INS(1) + 01(1) + LEN(1) + DATA(LEN) + UNIXTIME(4) + TOKEN(4)
    QByteArray frame(8, 0x00);
    if (ins == INS_GET_TOKEN) {
        frame[0] = ins;
        frame[1] = 0x01;
        frame[2] = 0x05;
        frame[3] = 0x00;

        QByteArray timeByteArr = getCurrentUnixTime();
        frame[4] = timeByteArr[3];
        frame[5] = timeByteArr[2];
        frame[6] = timeByteArr[1];
        frame[7] = timeByteArr[0];
    }
    else {
        int frameLength = 3+data.length() + 8;
        frame.resize(frameLength);
        frame[0] = ins;
        frame[1] = 0x01;
        frame[2] = data.length();
        for (int i = 0; i < data.length(); i++) {
            frame[3+i] = data[i];
        }

        QByteArray timeByteArr = getCurrentUnixTime();
        frame[frameLength-8] = timeByteArr[3];
        frame[frameLength-7] = timeByteArr[2];
        frame[frameLength-6] = timeByteArr[1];
        frame[frameLength-5] = timeByteArr[0];

        if (!token.isEmpty()) {
            frame[frameLength-4] = token[0];
            frame[frameLength-3] = token[1];
            frame[frameLength-2] = token[2];
            frame[frameLength-1] = token[3];
        }
    }

    return frame;
}

bool BLEClient::parseUpFrame(const QByteArray& cipherData, quint8& ins, QByteArray& data, QByteArray& token)
{
    if (cipherData.length() <= BLE_FRAME_MINI_LEN) return false;

    // 解析字段
    ins = static_cast<quint8>(cipherData[0]);
    quint8 dir = static_cast<quint8>(cipherData[1]);
    if (dir != 0x02) return false; // 上行指令固定为02

    quint8 len = static_cast<quint8>(cipherData[2]);
    data = cipherData.mid(3, len);
    token = cipherData.mid(3 + len + 4, 4); // UNIXTIME占4字节

    return true;
}

QString BLEClient::byteArrayToHex(const QByteArray& data)
{
    return data.toHex().toUpper();
}

QByteArray BLEClient::hexToByteArray(const QString& hexStr)
{
    return QByteArray::fromHex(hexStr.toUtf8());
}

QByteArray BLEClient::getCurrentUnixTime()
{
    quint32 time = QDateTime::currentSecsSinceEpoch();
    return QByteArray::fromRawData(reinterpret_cast<const char*>(&time), 4); // 小端模式
}

quint16 BLEClient::littleEndianToUInt16(const QByteArray& data)
{
    if (data.length() < 2) return 0;
    return static_cast<quint16>((static_cast<quint8>(data[1]) << 8) | static_cast<quint8>(data[0]));
}

quint32 BLEClient::littleEndianToUInt32(const QByteArray& data)
{
    if (data.length() < 4) return 0;
    return static_cast<quint32>((static_cast<quint8>(data[3]) << 24) |
                               (static_cast<quint8>(data[2]) << 16) |
                               (static_cast<quint8>(data[1]) << 8) |
                               static_cast<quint8>(data[0]));
}

QByteArray BLEClient::uint16ToLittleEndian(quint16 value)
{
    QByteArray data;
    data.append(static_cast<char>(value & 0xFF));
    data.append(static_cast<char>((value >> 8) & 0xFF));
    return data;
}

QByteArray BLEClient::uint32ToLittleEndian(quint32 value)
{
    QByteArray data;
    data.append(static_cast<char>(value & 0xFF));
    data.append(static_cast<char>((value >> 8) & 0xFF));
    data.append(static_cast<char>((value >> 16) & 0xFF));
    data.append(static_cast<char>((value >> 24) & 0xFF));
    return data;
}

quint16 BLEClient::calculateCRC16(const QByteArray& data)
{
    quint16 crc = 0xFFFF;
    for (char c : data) {
        crc ^= static_cast<quint8>(c);
        for (int i = 0; i < 8; i++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}

void BLEClient::sendCmdWithRetry(const QByteArray& frame, const QString& cmdName, int retryCount)
{
//    QMutexLocker locker(&m_mutex);
    qDebug() << "[sendCmdWithRetry]: " << !m_writeChar.isValid() << m_leController->state() << !m_targetService;
    if (!m_writeChar.isValid() || (m_leController && m_leController->state() != QLowEnergyController::DiscoveredState) || !m_targetService) {
        emit cmdSendResult(false, cmdName, "蓝牙未连接或写特征值/服务无效");
        return;
    }
    QMutexLocker retryLocker(&m_retryMutex);
    // 停止旧Timer并销毁
    if (m_cmdRetryTimers.contains(cmdName)) {
        QTimer* oldTimer = m_cmdRetryTimers.take(cmdName);
        oldTimer->stop();
        oldTimer->deleteLater();
    }

    m_cmdRetryCount[cmdName] = 0;
    m_cmdSendSuccess[cmdName] = false;
    m_cmdFrameCache[cmdName] = frame; // 缓存当前指令的帧数据
    retryLocker.unlock();

    QTimer* retryTimer = new QTimer(this);
    retryTimer->setSingleShot(true); // 单次触发，避免无限循环
    // 绑定Timer的超时信号到成员函数sendOnce
    connect(retryTimer, &QTimer::timeout, this, [=]() {
        sendOnce(cmdName, retryCount);
    });

    // 存储Timer并启动首次发送
    retryLocker.relock();
    m_cmdRetryTimers[cmdName] = retryTimer;
    retryLocker.unlock();

    // 立即执行首次发送（无需等Timer）
    sendOnce(cmdName, retryCount);
}

void BLEClient::sendOnce(const QString &cmdName, int retryCount)
{
    // 加锁读取当前指令的状态
    QMutexLocker retryLocker(&m_retryMutex);
    // 前置检查：指令是否存在（避免已清理的指令触发）
    if (!m_cmdRetryCount.contains(cmdName) || !m_cmdFrameCache.contains(cmdName)) {
        return;
    }

    int currentRetry = m_cmdRetryCount[cmdName];
    bool isSuccess = m_cmdSendSuccess[cmdName];
    QByteArray frame = m_cmdFrameCache[cmdName];
    retryLocker.unlock();

    // 终止条件1：指令已发送成功
    if (isSuccess) {
        qInfo() << "[BLE Send] 指令" << cmdName << "已成功，终止重传";
        // 清理Timer和状态
        QMutexLocker clearLocker(&m_retryMutex);
        if (m_cmdRetryTimers.contains(cmdName)) {
            QTimer* timer = m_cmdRetryTimers.take(cmdName);
            timer->stop();
            timer->deleteLater();
        }
        m_cmdRetryCount.remove(cmdName);
        m_cmdSendSuccess.remove(cmdName);
        m_cmdFrameCache.remove(cmdName);
        return;
    }

    // 终止条件2：重试次数耗尽
    if (currentRetry >= retryCount) {
        emit cmdSendResult(false, cmdName, QString("重传%1次失败").arg(retryCount));
        // 清理资源
        QMutexLocker clearLocker(&m_retryMutex);
        if (m_cmdRetryTimers.contains(cmdName)) {
            QTimer* timer = m_cmdRetryTimers.take(cmdName);
            timer->stop();
            timer->deleteLater();
        }
        m_cmdRetryCount.remove(cmdName);
        m_cmdSendSuccess.remove(cmdName);
        m_cmdFrameCache.remove(cmdName);
        return;
    }

    // 执行单次指令发送
//    qInfo() << "[BLE Send] 发送指令（第" << currentRetry + 1 << "次）：" << cmdName
//             << "，包数据：" << byteArrayToHex(frame);

    // 线程安全写特征值（加主锁）
//    QMutexLocker mainLocker(&m_mutex);
    if (m_targetService && m_writeChar.isValid() &&  (m_leController && m_leController->state() == QLowEnergyController::DiscoveredState)) {
        m_targetService->writeCharacteristic(m_writeChar, frame, QLowEnergyService::WriteWithResponse);
    }
//    mainLocker.unlock();

    // 更新重试次数
    retryLocker.relock();
    m_cmdRetryCount[cmdName] = currentRetry + 1;
    retryLocker.unlock();

    // 启动下一次重传Timer
    QMutexLocker timerLocker(&m_retryMutex);
    if (m_cmdRetryTimers.contains(cmdName)) {
        QTimer* timer = m_cmdRetryTimers[cmdName];
        timer->setInterval(BLE_RETRY_DELAY);
        timer->start(); // 启动Timer，超时后触发sendOnce
    }
    timerLocker.unlock();
}

QList<QByteArray> BLEClient::splitMultiPackData(const QByteArray& data, int packSize)
{
    QList<QByteArray> packList;
    int totalLen = data.length();
    int packCount = (totalLen + packSize - 1) / packSize;

    for (int i = 0; i < packCount; i++) {
        int start = i * packSize;
        int len = qMin(packSize, totalLen - start);
        packList.append(data.mid(start, len));
    }

    return packList;
}

bool BLEClient::parseMultiPackField(const QByteArray& dataField, quint16& total, quint16& idx, quint16& crc, quint16& size, QByteArray& data)
{
    // 协议格式：IDX(2) + TOTAL(2) + RES(1) + CRC(2) + SIZE(2) + DATA(SIZE)
    // 最小长度：2+2+1+2+2=9字节
    if (dataField.size() < 9) {
        qWarning() << "[BLE MultiPack] 上行多包字段长度不足（最小9字节）";
        return false;
    }

    // 提取字段
    total = littleEndianToUInt16(dataField.mid(1, 2));  // 总包数
    idx = littleEndianToUInt16(dataField.mid(3, 2));    // 当前包索引
    crc = littleEndianToUInt16(dataField.mid(5, 2));   // 包CRC校验值
    size = littleEndianToUInt16(dataField.mid(7, 2));  // 包DATA长度
    data = dataField.mid(9, size);                   // 包DATA

    // 校验索引和总包数合法性
    if (idx >= total) {
        qWarning() << "[BLE MultiPack] 上行包索引超出范围（IDX=" << idx << "，TOTAL=" << total << "）";
        return false;
    }

    // 校验DATA长度
    if (data.size() != size) {
        qWarning() << "[BLE MultiPack] 上行包DATA长度不匹配（实际=" << data.size() << "，预期=" << size << "）";
        return false;
    }

    // 校验CRC（接收端计算vs上行返回的CRC）
    quint16 calcCRC = calculateCRC16(data);
    if (calcCRC != crc) {
        qWarning() << "[BLE MultiPack] 上行包CRC校验失败（计算=" << calcCRC << "，接收=" << crc << "）";
        return false;
    }

    return true;
}

QByteArray BLEClient::mergeMultiPackData()
{
    QByteArray mergedData;

    if (!m_multiPackRecvState.isCompleted) {
        qWarning() << "[BLE MultiPack] 多包未接收完成，无法拼接";
        return mergedData;
    }

    // 按索引顺序拼接（0~TOTAL-1）
    for (quint16 idx = 0; idx < m_multiPackRecvState.totalPack; idx++) {
        if (m_multiPackRecvState.packCache.contains(idx)) {
            mergedData.append(m_multiPackRecvState.packCache[idx]);
        }
        else {
            qWarning() << "[BLE MultiPack] 拼接失败：缺失IDX=" << idx << "的包";
            mergedData.clear();
            break;
        }
    }

    // 拼接完成后重置状态
    resetMultiPackRecvState();
    return mergedData;
}

void BLEClient::resetMultiPackRecvState()
{
    m_multiPackRecvState.totalPack = 0;
    m_multiPackRecvState.receivedCount = 0;
    m_multiPackRecvState.packCache.clear();
    m_multiPackRecvState.isCompleted = false;
    m_multiPackRecvState.timeoutTimer.stop();
}

bool BLEClient::parseWorkTicketSendResp(const QByteArray& dataField, quint16& respIdx, quint16& respTotal, quint8& respRes)
{
    // 设备上行响应数据格式：IDX(2) + TOTAL(2) + RES(1)
    if (dataField.size() < 5) {
        qWarning() << "[BLE WorkTicket Send] 响应格式错误（长度不足5字节）";
        return false;
    }

    respIdx = littleEndianToUInt16(dataField.mid(0, 2));    // 当前包索引
    respTotal = littleEndianToUInt16(dataField.mid(2, 2));  // 总包数
    respRes = static_cast<quint8>(dataField[4]);          // 处理结果（0=成功)

    // 校验总包数一致性
    if (respTotal != m_workTicketSendState.totalPack) {
        qWarning() << "[BLE WorkTicket Send] 响应总包数不匹配（本地" << m_workTicketSendState.totalPack << "，设备" << respTotal << "）";
        return false;
    }

    // 校验索引一致性
    if (respIdx != m_workTicketSendState.currentIdx) {
        qWarning() << "[BLE WorkTicket Send] 响应索引不匹配（本地" << m_workTicketSendState.currentIdx << "，设备" << respIdx << "）";
        return false;
    }

    return true;
}

void BLEClient::resetWorkTicketSendState()
{
    QMutexLocker locker(&m_workTicketSendMutex);
    m_workTicketSendState.totalPack = 0;
    m_workTicketSendState.currentIdx = 0;
    m_workTicketSendState.packList.clear();
    m_workTicketSendState.isCompleted = false;
    m_workTicketSendState.retryCount = 0;
    m_workTicketSendState.packTimeoutTimer.stop();
}

void BLEClient::getToken()
{
    // 获取令牌指令
    QByteArray frame = buildDownFrame(INS_GET_TOKEN, QByteArray(), QByteArray(4, 0x00));
    sendCmdWithRetry(frame, "获取令牌");
}

void BLEClient::switchDeviceMode(bool isWorkMode)
{
    // 模式切换：SUB_CMD=0x01，JOB=01（工作）/02（待机）
    QByteArray dataField;
    dataField.append(SEND_MODE_SWITCH);
    dataField.append(isWorkMode ? 0x01 : 0x02);

    QByteArray frame = buildDownFrame(INS_SEND_CMD, dataField, m_token);
    sendCmdWithRetry(frame, isWorkMode ? "工作模式切换" : "待机模式切换");
}

void BLEClient::sendWorkTicket(const BLERWorkTicket& workTicket)
{
//    QMutexLocker locker(&m_workTicketSendMutex);
    // 1. 检查是否有正在进行的下发任务
    if (!m_workTicketSendState.packList.isEmpty() && !m_workTicketSendState.isCompleted) {
        qWarning() << "[BLE WorkTicket Send] 已有工作票下发任务进行中，拒绝重复发起";
        emit cmdSendResult(false, "工作票下发", "存在未完成任务");
        return;
    }
    resetWorkTicketSendState();

    QByteArray jsonRaw = workTicket.ticketDoc.toJson(QJsonDocument::Compact);

    // 2. 分割多包（除最后一包外，每包固定128字节）
    QList<QByteArray> rawPackList = splitMultiPackData(jsonRaw, 128);
    m_workTicketSendState.totalPack = rawPackList.size();
    if (m_workTicketSendState.totalPack == 0) {
        qWarning() << "[BLE WorkTicket Send] 工作票数据为空，下发失败";
        emit cmdSendResult(false, "工作票下发", "数据为空");
        return;
    }

    // 2. 构建每包完整数据（协议：TOTAL(2)+IDX(2)+CRC(2)+SIZE(2)+DATA(SIZE)）
    for (quint16 idx = 0; idx < m_workTicketSendState.totalPack; idx++) {
        QByteArray packData = rawPackList[idx];
        QByteArray packFrame;
        // TOTAL（2字节小端）
        packFrame.append(uint16ToLittleEndian(m_workTicketSendState.totalPack));
        // IDX（2字节小端）
        packFrame.append(uint16ToLittleEndian(idx));
        // CRC（2字节小端：DATA的CRC-16/MODBUS）
        quint16 crc = calculateCRC16(packData);
        packFrame.append(uint16ToLittleEndian(crc));
        // SIZE（2字节小端）
        packFrame.append(uint16ToLittleEndian(packData.size()));
        // DATA（压缩后的JSON分片）
        packFrame.append(packData);
        m_workTicketSendState.packList.append(packFrame);
    }

    qInfo() << "[BLE WorkTicket Send] 工作票分割为" << m_workTicketSendState.totalPack << "包，开始下发";
    // 4. 启动第一包发送
    m_workTicketSendState.currentIdx = 0;
    m_workTicketSendState.retryCount = 0;
    sendNextWorkTicketPack();
}

void BLEClient::sendNextWorkTicketPack()
{
//    QMutexLocker locker(&m_workTicketSendMutex);
    // 1. 检查下发是否完成
    if (m_workTicketSendState.currentIdx >= m_workTicketSendState.totalPack) {
        m_workTicketSendState.isCompleted = true;
        qInfo() << "[BLE WorkTicket Send] 所有包下发完成（共" << m_workTicketSendState.totalPack << "包）";
        emit cmdSendResult(true, "工作票下发", "多包传输完成");

        emit signalSendJobTicketStatus(true);
        resetWorkTicketSendState();

        // 完成作业票之后切换工作模式
        switchDeviceMode(true);
        return;
    }

    // 2. 获取当前包数据
    QByteArray currentPack = m_workTicketSendState.packList[m_workTicketSendState.currentIdx];
    // 3. 构建下行指令帧（协议：INS=02（指令下发），SUB_CMD=02（工作票下发））
    QByteArray dataField;
    dataField.append(SEND_WORK_TICKET); // 子指令：工作票下发（0x02）
    dataField.append(currentPack);      // 多包字段（TOTAL+IDX+CRC+SIZE+DATA）
    QByteArray frame = buildDownFrame(INS_SEND_CMD, dataField, m_token);

    // 4. 发送当前包（带重试机制，单包重试3次）
    qInfo() << "[BLE WorkTicket Send] 发送第" << m_workTicketSendState.currentIdx << "/" << m_workTicketSendState.totalPack << "包（大小：" << currentPack.size() << "字节）";
    sendCmdWithRetry(frame, QString("工作票下发第%1包").arg(m_workTicketSendState.currentIdx), 1); // 单包独立重试1次，超时由状态机处理

    // 5. 启动单包超时定时器
    m_workTicketSendState.packTimeoutTimer.start();
}

void BLEClient::setChargeParam(quint8 startPercent, quint8 stopPercent)
{
    // 充电参数设置：SUB_CMD=0x04，START+STOP（各1字节）
    QByteArray dataField;
    dataField.append(SEND_CHARGE_PARAM);
    dataField.append(startPercent);
    dataField.append(stopPercent);

    QByteArray frame = buildDownFrame(INS_SEND_CMD, dataField, m_token);
    sendCmdWithRetry(frame, QString("充电参数设置（开启%1%，终止%2%）").arg(startPercent).arg(stopPercent));
}

void BLEClient::sendDisconnectCmd()
{
    // 蓝牙断开：SUB_CMD=0xEA
    QByteArray dataField;
    dataField.append(SEND_DISCONNECT);

    QByteArray frame = buildDownFrame(INS_SEND_CMD, dataField, m_token);
    sendCmdWithRetry(frame, "蓝牙断开指令");
}

void BLEClient::sendShutdownCmd(bool isShutdown)
{
    // 关机指令：SUB_CMD=0xEE，STAT=01（重启）/02（关机）
    QByteArray dataField;
    dataField.append(SEND_SHUTDOWN);
    dataField.append(isShutdown ? 0x02 : 0x01);

    QByteArray frame = buildDownFrame(INS_SEND_CMD, dataField, m_token);
    sendCmdWithRetry(frame, isShutdown ? "设备关机" : "设备重启");
}

void BLEClient::getDeviceStatus()
{
    // 获取设备状态：INS=03，SUB_CMD=0x01
    QByteArray dataField;
    dataField.append(UPLOAD_DEVICE_STATUS);

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);
    sendCmdWithRetry(frame, "获取设备状态");
}

void BLEClient::getWorkTicketOtherData()
{
    QByteArray dataField;
    dataField.append(UPLOAD_WORK_TICKET);
    dataField.append(uint16ToLittleEndian(m_multiPackRecvState.currentIdx));
    dataField.append(uint16ToLittleEndian(m_multiPackRecvState.totalPack));
    dataField.append(static_cast<char>(0x00 & 0xFF));

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);

    sendCmdWithRetry(frame, "获取工作票子包");
}

void BLEClient::getWorkTicketResult()
{
    // 获取工作票结果：INS=03，SUB_CMD=0x02
    QByteArray dataField;
    dataField.append(UPLOAD_WORK_TICKET);

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);
    sendCmdWithRetry(frame, "获取工作票完成情况");
}

void BLEClient::getBatteryStatus()
{
    // 获取电量：INS=03，SUB_CMD=0x03
    QByteArray dataField;
    dataField.append(UPLOAD_BATTERY);

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);
    sendCmdWithRetry(frame, "获取钥匙电量");
}

void BLEClient::getRFID()
{
    // 获取RFID：INS=03，SUB_CMD=0x04
    QByteArray dataField;
    dataField.append(UPLOAD_RFID);

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);
    sendCmdWithRetry(frame, "获取RFID号");
}

void BLEClient::getChargeParam()
{
    // 获取充电参数：INS=03，SUB_CMD=0x05
    QByteArray dataField;
    dataField.append(UPLOAD_CHARGE_PARAM);

    QByteArray frame = buildDownFrame(INS_UPLOAD_DATA, dataField, m_token);
    sendCmdWithRetry(frame, "获取充电参数");
}

void BLEClient::getFirmwareVersion()
{
    // 获取固件版本：INS=0xEE
    QByteArray dataField;
    dataField.append(0x01); // 固定参数

    QByteArray frame = buildDownFrame(INS_GET_FIRMWARE, dataField, m_token);
    sendCmdWithRetry(frame, "获取固件版本");
}

void BLEClient::onCharacteristicChanged(const QLowEnergyCharacteristic& chara, const QByteArray& data)
{
    QMutexLocker locker(&m_mutex);
    // 仅处理目标通知特征值（FED1）的数据
    if (chara.uuid().toUInt16() != BLE_CHAR_INDICATE_UUID) {
        qWarning() << "[BLE Recv] 未知特征值数据，忽略：" << chara.uuid().toString();
        return;
    }

//    qInfo() << "[BLE Recv] 收到通知数据（长度：" << data.length() << "）：" << byteArrayToHex(data);

    // 校验数据长度（协议要求加密后固定16字节）
    if (data.length() < 8) {
        qWarning() << "[BLE Recv] 数据长度不合法，丢弃";
        return;
    }

    // 解析上行加密帧（解密+协议解析）
    quint8 ins = 0;
    QByteArray dataField;
    QByteArray token;
    if (!parseUpFrame(data, ins, dataField, token)) {
        qWarning() << "[BLE Recv] 帧解析失败（解密或格式错误）";
        return;
    }

    // 根据指令类型（INS）处理不同业务响应
    switch (ins) {
        case INS_GET_TOKEN: {
            // 处理「获取令牌」响应（DATA字段为4字节令牌）
            BLEToken tokenResp;
            if (dataField.length() == 4) {
                tokenResp.success = true;
                tokenResp.token = dataField;
                m_token = dataField; // 缓存令牌
                qInfo() << "[BLE Recv] 令牌获取成功：" << byteArrayToHex(dataField);
            }
            else {
                qWarning() << "[BLE Recv] 令牌数据长度错误：" << dataField.length();
            }
            emit tokenReceived(tokenResp); // 发射令牌获取结果信号
            break;
        }
        case INS_SEND_CMD: {
            // 处理「指令下发」响应（格式：SUB_CMD(1) + RES(1) + 附加数据）
            if (dataField.length() < 2) {
                qWarning() << "[BLE Recv] 指令响应数据过短：" << dataField.length();
                break;
            }
            quint8 subCmd = static_cast<quint8>(dataField[0]);
            quint8 res = static_cast<quint8>(dataField[1]);
            bool success = (res == 0x01); // 0x01=成功，0x02=失败
            QString cmdName = "未知指令";

            if (subCmd == SEND_MODE_SWITCH) cmdName = "模式切换";
            else if (subCmd == SEND_WORK_TICKET){
                cmdName = "工作票下发";
                QMutexLocker locker(&m_workTicketSendMutex);
                // 解析多包响应字段
                quint16 respIdx, respTotal;
                quint8 respRes;
                if (!parseWorkTicketSendResp(dataField.mid(1), respIdx, respTotal, respRes)) {
                    // 响应解析失败，触发当前包重传
                    m_workTicketSendState.retryCount++;
                    if (m_workTicketSendState.retryCount <= BLE_RETRY_COUNT) {
                        qInfo() << "[BLE WorkTicket Send] 响应解析失败，第" << m_workTicketSendState.retryCount << "次重传第" << respIdx << "包";
                    }
                    else {
                        qWarning() << "[BLE WorkTicket Send] 第" << respIdx << "包响应解析失败，下发终止";
                        resetWorkTicketSendState();
                        emit cmdSendResult(false, cmdName, "第" + QString::number(respIdx) + "包响应解析失败");
                    }
                    break;
                }

                // 处理响应结果
                if (respRes == 0) {
                    // 当前包发送成功，准备发送下一包
                    qInfo() << "[BLE WorkTicket Send] 第" << respIdx << "包发送成功（RES=0）";
                    m_workTicketSendState.currentIdx++;
                    m_workTicketSendState.retryCount = 0; // 重置当前包重试次数
                }
                else {
                    // 当前包发送失败，重传
                    m_workTicketSendState.retryCount++;
                    if (m_workTicketSendState.retryCount <= BLE_RETRY_COUNT) {
                        qWarning() << "[BLE WorkTicket Send] 第" << respIdx << "包发送失败（RES=" << respRes << "），第" << m_workTicketSendState.retryCount << "次重传";
                    }
                    else {
                        qCritical() << "[BLE WorkTicket Send] 第" << respIdx << "包重传" << BLE_RETRY_COUNT << "次失败（RES=" << respRes << "）";
                        resetWorkTicketSendState();
                        emit cmdSendResult(false, cmdName, "第" + QString::number(respIdx) + "包发送失败（RES=" + QString::number(respRes) + "）");
                    }
                }
                break;
            }
            else if (subCmd == SEND_CHARGE_PARAM) cmdName = "充电参数设置";
            else if (subCmd == SEND_DISCONNECT) cmdName = "蓝牙断开";
            else if (subCmd == SEND_SHUTDOWN) cmdName = "设备关机/重启";

            qInfo() << "[BLE Recv] " << cmdName << "响应：" << (success ? "成功" : "失败");
            emit cmdSendResult(success, cmdName, success ? "执行成功" : "执行失败");
            break;
        }
        case INS_UPLOAD_DATA: {
            // 处理「数据上传」响应（格式：SUB_CMD(1) + 数据内容）
            if (dataField.length() < 1) {
                qWarning() << "[BLE Recv] 数据上传响应格式错误";
                break;
            }
            quint8 subCmd = static_cast<quint8>(dataField[0]);

            switch (subCmd) {
                case UPLOAD_DEVICE_STATUS: {
                    // 设备状态响应：SUB_CMD(1) + STATUS(1)
                    BLEDeviceStatus status;
                    if (dataField.length() >= 2) {
                        quint8 statusCode = static_cast<quint8>(dataField[1]);
                        status.success = true;
                        if (statusCode == BLEDeviceStatus::WORK_MODE) {
                            status.status = BLEDeviceStatus::WORK_MODE;
                            status.statusDesc = "工作模式";
                        }
                        else if (statusCode == BLEDeviceStatus::STANDBY_MODE) {
                            status.status = BLEDeviceStatus::STANDBY_MODE;
                            status.statusDesc = "待机模式";
                        }
                        else if (statusCode == BLEDeviceStatus::FAULT_MODE) {
                            status.status = BLEDeviceStatus::FAULT_MODE;
                            status.statusDesc = "故障模式";
                        }
                        else {
                            status.statusDesc = "未知模式";
                        }
                        qInfo() << "[BLE Recv] 设备状态：" << status.statusDesc;
                    }
                    else {
                        qWarning() << "[BLE Recv] 设备状态数据不完整";
                    }
                    emit deviceStatusReceived(status);
                    break;
                }
                case UPLOAD_BATTERY: {
                    // 电量状态响应：SUB_CMD(1) + BATTERY(1) + CHARGE_STATE(1)
                    BLEChargeParam chargeState;
                    quint8 battery = 0;
                    if (dataField.length() >= 3) {
                        battery = static_cast<quint8>(dataField[1]);
                        quint8 chargeCode = static_cast<quint8>(dataField[2]);
                        chargeState.success = true;

                        if (chargeCode == BLEChargeParam::UNCHARGED) {
                            chargeState.chargeState = BLEChargeParam::UNCHARGED;
                            chargeState.chargeStateDesc = "未充电";
                        }
                        else if (chargeCode == BLEChargeParam::CHARGING) {
                            chargeState.chargeState = BLEChargeParam::CHARGING;
                            chargeState.chargeStateDesc = "充电中";
                        }
                        else if (chargeCode == BLEChargeParam::FULL) {
                            chargeState.chargeState = BLEChargeParam::FULL;
                            chargeState.chargeStateDesc = "充满电";
                        }
                        else {
                            chargeState.chargeStateDesc = "未知充电状态";
                        }
                        qInfo() << "[BLE Recv] 钥匙电量：" << static_cast<int>(battery) << "%"
                                 << "，充电状态：" << chargeState.chargeStateDesc;
                    }
                    else {
                        qWarning() << "[BLE Recv] 电量数据不完整";
                    }
                    emit batteryStatusReceived(battery, chargeState);
                    break;
                }
                case UPLOAD_RFID: {
                    // RFID信息响应：SUB_CMD(1) + COUNT(1) + RFID_1(8) + RFID_2(8) + ...
                    BLERFIDInfo rfidInfo;
                    if (dataField.length() >= 2) {
                        quint8 rfidCount = static_cast<quint8>(dataField[1]);
                        int expectedLen = 2 + rfidCount * 8; // 2=SUB_CMD+COUNT，每个RFID占8字节
                        if (dataField.length() >= expectedLen) {
                            rfidInfo.success = true;
                            for (int i = 0; i < rfidCount; i++) {
                                int startIdx = 2 + i * 8;
                                QByteArray rfidBytes = dataField.mid(startIdx, 8);
                                rfidInfo.rfidList.append(byteArrayToHex(rfidBytes));
                            }
                            qInfo() << "[BLE Recv] 读取到RFID数量：" << rfidCount
                                     << "，列表：" << rfidInfo.rfidList.join(", ");
                        }
                        else {
                            qWarning() << "[BLE Recv] RFID数据长度不足";
                        }
                    }
                    else {
                        qWarning() << "[BLE Recv] RFID数据格式错误";
                    }
                    emit rfidReceived(rfidInfo);
                    break;
                }
                case UPLOAD_CHARGE_PARAM: {
                    // 充电参数响应：SUB_CMD(1) + START_PERCENT(1) + STOP_PERCENT(1) + CHARGE_STATE(1)
                    BLEChargeParam param;
                    if (dataField.length() >= 4) {
                        param.success = true;
                        param.startPercent = static_cast<quint8>(dataField[1]);
                        param.stopPercent = static_cast<quint8>(dataField[2]);
                        quint8 chargeCode = static_cast<quint8>(dataField[3]);

                        if (chargeCode == BLEChargeParam::UNCHARGED) {
                            param.chargeState = BLEChargeParam::UNCHARGED;
                            param.chargeStateDesc = "未充电";
                        } else if (chargeCode == BLEChargeParam::CHARGING) {
                            param.chargeState = BLEChargeParam::CHARGING;
                            param.chargeStateDesc = "充电中";
                        } else if (chargeCode == BLEChargeParam::FULL) {
                            param.chargeState = BLEChargeParam::FULL;
                            param.chargeStateDesc = "充满电";
                        }

                        qInfo() << "[BLE Recv] 充电参数：开启" << static_cast<int>(param.startPercent) << "%"
                                 << "，终止" << static_cast<int>(param.stopPercent) << "%";
                    } else {
                        qWarning() << "[BLE Recv] 充电参数数据不完整";
                    }
                    emit chargeParamReceived(param);
                    break;
                }
                case UPLOAD_WORK_TICKET: {
                // 工作票完成情况（上行多包数据）
                    BLERWorkTicketResult result;
                    QMutexLocker locker(&m_multiPackRecvMutex);

                    // 1. 解析上行多包字段（从dataField提取TOTAL/IDX/CRC等）
                    quint16 totalPack, idx, crc, size;
                    QByteArray packData;
                    if (!parseMultiPackField(dataField, totalPack, idx, crc, size, packData)) {
                        break;
                    }

                    // 2. 初始化多包状态（首次接收该任务的包）
                    if (idx == 0) {
                        resetMultiPackRecvState();
                        m_multiPackRecvState.totalPack = totalPack;
                        m_multiPackRecvState.timeoutTimer.start(); // 启动超时
                        qInfo() << "[BLE MultiPack] 开始接收工作票多包数据（总包数=" << totalPack << "）";
                    }

                    // 3. 缓存当前包（去重）
                    if (!m_multiPackRecvState.packCache.contains(idx)) {
                        m_multiPackRecvState.currentIdx = idx;
                        m_multiPackRecvState.packCache.insert(idx, packData);
                        m_multiPackRecvState.receivedCount++;
                    }

                    // 4. 检查是否所有包接收完成
                    if (m_multiPackRecvState.receivedCount == m_multiPackRecvState.totalPack) {
                        m_multiPackRecvState.isCompleted = true;
                        m_multiPackRecvState.timeoutTimer.stop();
                        qInfo() << "[BLE MultiPack] 工作票多包接收完成（已接收=" << m_multiPackRecvState.receivedCount << "包）";

                        // 5. 拼接多包数据
                        QByteArray mergedData = mergeMultiPackData();
                        if (mergedData.isEmpty()) {
                            break;
                        }

                        // 6. 解压+解析JSON（协议要求工作票需压缩）
                        QByteArray uncompressedData = qUncompress(mergedData);
                        if (uncompressedData.isEmpty()) {
                            uncompressedData = mergedData; // 兼容未压缩情况
                            qInfo() << "[BLE MultiPack] 工作票数据未压缩，直接解析";
                        }

                        // 7. 解析JSON并校验字段
                        QJsonParseError parseErr;
                        QJsonDocument jsonDoc = QJsonDocument::fromJson(uncompressedData, &parseErr);
                        if (parseErr.error != QJsonParseError::NoError || !jsonDoc.isObject()) {
                            qWarning() << "[BLE MultiPack] 工作票JSON解析失败：" << parseErr.errorString();
                            break;
                        }

                        // 8. 校验必需字段（协议4.5.2节）
                        QJsonObject rootObj = jsonDoc.object();
                        if (!rootObj.contains("cardNo") || !rootObj.contains("data")) {
                            qWarning() << "[BLE MultiPack] 工作票缺失必需字段（cardNo/data）";
                            break;
                        }

                        // 9. 发射结果信号
                        result.success = true;
                        result.resultDoc = jsonDoc;
                        emit workTicketResultReceived(result);
                        qInfo() << "[BLE MultiPack] 工作票多包接收+解析完成" << jsonDoc;
                    }
                    else {
                        // 未完成，更新超时定时器
                        m_multiPackRecvState.timeoutTimer.start();
                        qInfo() << "[BLE MultiPack] 接收工作票包（IDX=" << idx << "，已接收=" << m_multiPackRecvState.receivedCount << "/" << m_multiPackRecvState.totalPack << "）";
                    }
                    break;
                }
                default:
                    qWarning() << "[BLE Recv] 未知数据上传子指令：" << subCmd;
                    break;
            }
            break;
        }
        case INS_GET_FIRMWARE: {
            // 固件版本响应：DATA字段为「软版本(4) + 硬版本(4)」
            if (dataField.length() >= 8) {
                QString softVersion = byteArrayToHex(dataField.mid(0, 4));
                QString hardVersion = byteArrayToHex(dataField.mid(4, 4));
                // 格式化版本号（示例：0100 → V1.00）
                softVersion = QString("V%1.%2").arg(softVersion.mid(0, 2)).arg(softVersion.mid(2, 2));
                hardVersion = QString("V%1.%2").arg(hardVersion.mid(0, 2)).arg(hardVersion.mid(2, 2));
                qInfo() << "[BLE Recv] 固件版本 - 软件：" << softVersion << "，硬件：" << hardVersion;
                emit firmwareVersionReceived(softVersion, hardVersion);
            } else {
                qWarning() << "[BLE Recv] 固件版本数据不完整";
            }
            break;
        }

        default:
            qWarning() << "[BLE Recv] 未知指令类型（INS）：" << ins;
            break;
    }
}

void BLEClient::onWriteCharacteristicFinished(const QLowEnergyCharacteristic& chara, const QByteArray& newValue)
{
//    QMutexLocker locker(&m_mutex);
    // 仅处理目标写特征值（FED2）的回调
    if (chara.uuid().toUInt16() != BLE_CHAR_WRITE_UUID) {
        qWarning() << "[BLE Write] 未知特征值写完成回调，忽略：" << chara.uuid().toString();
        return;
    }

//    qInfo() << "[BLE Write] 指令发送完成，发送数据：" << byteArrayToHex(newValue);

    QMutexLocker retryLocker(&m_retryMutex);
    for (auto it = m_cmdSendSuccess.begin(); it != m_cmdSendSuccess.end(); ++it) {
        it.value() = true;
    }
    retryLocker.unlock();
}
